mioku-service-ai 2.2.0 → 2.2.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/index.ts +37 -17
- package/package.json +4 -2
package/index.ts
CHANGED
|
@@ -8,7 +8,11 @@ import type {
|
|
|
8
8
|
} from "openai/resources/chat/completions";
|
|
9
9
|
import type { AISkill, AITool, MiokuService } from "mioku";
|
|
10
10
|
import { createAIUsageStore } from "./usage/store";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
UsageTracker,
|
|
13
|
+
extractUsageTokens,
|
|
14
|
+
mergeMeasuredTokens,
|
|
15
|
+
} from "./usage/tracker";
|
|
12
16
|
import {
|
|
13
17
|
runToolLoop,
|
|
14
18
|
parseToolArguments,
|
|
@@ -68,7 +72,9 @@ class AIInstanceImpl implements AIInstance {
|
|
|
68
72
|
: [...options.messages];
|
|
69
73
|
|
|
70
74
|
// Some upstreams reject system-only requests with 400 "chat content is empty".
|
|
71
|
-
const messages: ChatCompletionMessageParam[] = composed.some(
|
|
75
|
+
const messages: ChatCompletionMessageParam[] = composed.some(
|
|
76
|
+
(m) => m.role === "user",
|
|
77
|
+
)
|
|
72
78
|
? composed
|
|
73
79
|
: [...composed, { role: "user", content: "." }];
|
|
74
80
|
|
|
@@ -94,8 +100,8 @@ class AIInstanceImpl implements AIInstance {
|
|
|
94
100
|
? [{ role: "system", content: options.prompt }, ...messages]
|
|
95
101
|
: messages;
|
|
96
102
|
|
|
97
|
-
const withUserTurn: ChatCompletionMessageParam[] = composed.some(
|
|
98
|
-
m.role === "user",
|
|
103
|
+
const withUserTurn: ChatCompletionMessageParam[] = composed.some(
|
|
104
|
+
(m) => m.role === "user",
|
|
99
105
|
)
|
|
100
106
|
? composed
|
|
101
107
|
: [...composed, { role: "user", content: "." }];
|
|
@@ -221,8 +227,10 @@ class AIInstanceImpl implements AIInstance {
|
|
|
221
227
|
model: args.model,
|
|
222
228
|
messages: args.messages,
|
|
223
229
|
tools: args.tools,
|
|
224
|
-
|
|
225
|
-
...(args.max_tokens != null && {
|
|
230
|
+
temperature: args.temperature,
|
|
231
|
+
...(args.max_tokens != null && {
|
|
232
|
+
max_tokens: args.max_tokens,
|
|
233
|
+
}),
|
|
226
234
|
});
|
|
227
235
|
|
|
228
236
|
const message = response.choices[0]?.message;
|
|
@@ -267,9 +275,9 @@ class AIInstanceImpl implements AIInstance {
|
|
|
267
275
|
model: args.model,
|
|
268
276
|
messages: args.messages,
|
|
269
277
|
tools: args.tools,
|
|
270
|
-
|
|
278
|
+
temperature: args.temperature,
|
|
271
279
|
stream: true,
|
|
272
|
-
...(args.max_tokens != null && {
|
|
280
|
+
...(args.max_tokens != null && { max_tokens: args.max_tokens }),
|
|
273
281
|
});
|
|
274
282
|
|
|
275
283
|
let content = "";
|
|
@@ -283,7 +291,8 @@ class AIInstanceImpl implements AIInstance {
|
|
|
283
291
|
for await (const chunk of stream as AsyncIterable<any>) {
|
|
284
292
|
const choice = chunk?.choices?.[0];
|
|
285
293
|
const chunkUsage = extractUsageTokens(chunk);
|
|
286
|
-
if (chunkUsage)
|
|
294
|
+
if (chunkUsage)
|
|
295
|
+
streamUsage = mergeMeasuredTokens(streamUsage, chunkUsage);
|
|
287
296
|
const delta = choice?.delta;
|
|
288
297
|
if (!delta) continue;
|
|
289
298
|
|
|
@@ -299,11 +308,17 @@ class AIInstanceImpl implements AIInstance {
|
|
|
299
308
|
reasoning += delta.reasoning;
|
|
300
309
|
}
|
|
301
310
|
|
|
302
|
-
const deltaToolCalls = Array.isArray(delta.tool_calls)
|
|
311
|
+
const deltaToolCalls = Array.isArray(delta.tool_calls)
|
|
312
|
+
? delta.tool_calls
|
|
313
|
+
: [];
|
|
303
314
|
for (const item of deltaToolCalls) {
|
|
304
315
|
const index =
|
|
305
316
|
typeof item?.index === "number" && item.index >= 0 ? item.index : 0;
|
|
306
|
-
const acc = toolCallsByIndex.get(index) || {
|
|
317
|
+
const acc = toolCallsByIndex.get(index) || {
|
|
318
|
+
id: "",
|
|
319
|
+
name: "",
|
|
320
|
+
arguments: "",
|
|
321
|
+
};
|
|
307
322
|
if (typeof item?.id === "string" && item.id) acc.id = item.id;
|
|
308
323
|
if (typeof item?.function?.name === "string" && item.function.name) {
|
|
309
324
|
acc.name += item.function.name;
|
|
@@ -390,7 +405,10 @@ class AIInstanceImpl implements AIInstance {
|
|
|
390
405
|
}
|
|
391
406
|
return (messages as MultimodalMessage[]).map((msg) => {
|
|
392
407
|
if (typeof msg.content === "string") {
|
|
393
|
-
return {
|
|
408
|
+
return {
|
|
409
|
+
role: msg.role,
|
|
410
|
+
content: msg.content,
|
|
411
|
+
} as ChatCompletionMessageParam;
|
|
394
412
|
}
|
|
395
413
|
return {
|
|
396
414
|
role: msg.role,
|
|
@@ -407,7 +425,8 @@ class AIInstanceImpl implements AIInstance {
|
|
|
407
425
|
}
|
|
408
426
|
|
|
409
427
|
registerPrompt(name: string, prompt: string): boolean {
|
|
410
|
-
if (this.prompts.has(name))
|
|
428
|
+
if (this.prompts.has(name))
|
|
429
|
+
logger.warn(`Prompt ${name} already exists, overwriting`);
|
|
411
430
|
this.prompts.set(name, prompt);
|
|
412
431
|
logger.info(`Prompt ${name} registered successfully`);
|
|
413
432
|
return true;
|
|
@@ -525,7 +544,9 @@ class AIServiceImpl implements AIService {
|
|
|
525
544
|
}
|
|
526
545
|
this.globalSkills.set(skill.name, skill);
|
|
527
546
|
this.rebuildToolIndex();
|
|
528
|
-
logger.info(
|
|
547
|
+
logger.info(
|
|
548
|
+
`Skill ${skill.name} registered with ${skill.tools.length} tools`,
|
|
549
|
+
);
|
|
529
550
|
return true;
|
|
530
551
|
}
|
|
531
552
|
|
|
@@ -603,9 +624,8 @@ function extractTextContent(
|
|
|
603
624
|
if (typeof content === "string") return content;
|
|
604
625
|
if (!Array.isArray(content)) return "";
|
|
605
626
|
return content
|
|
606
|
-
.filter(
|
|
607
|
-
(part
|
|
608
|
-
Boolean(part && part.type === "text"),
|
|
627
|
+
.filter((part): part is { type: "text"; text: string } =>
|
|
628
|
+
Boolean(part && part.type === "text"),
|
|
609
629
|
)
|
|
610
630
|
.map((part) => part.text)
|
|
611
631
|
.join("\n")
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mioku-service-ai",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "为插件提供完整的ai服务支持,包括ai实例管理,提示词管理,skills管理等",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"keywords": [
|
|
7
|
+
"keywords": [
|
|
8
|
+
"mioku"
|
|
9
|
+
],
|
|
8
10
|
"repository": {
|
|
9
11
|
"type": "git",
|
|
10
12
|
"url": "https://github.com/mioku-lab/mioku.git"
|