koishi-plugin-chatluna-affinity 0.2.3-alpha.3 → 0.2.3

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/client/types.ts CHANGED
@@ -19,6 +19,9 @@ export interface Config {
19
19
  schedule?: {
20
20
  enabled?: boolean
21
21
  model?: string
22
+ personaSource?: 'none' | 'chatluna' | 'custom'
23
+ personaChatlunaPreset?: string
24
+ personaCustomPreset?: string
22
25
  variableName?: string
23
26
  currentVariableName?: string
24
27
  registerTool?: boolean
package/lib/index.d.ts CHANGED
@@ -14,4 +14,4 @@ export * from './renders';
14
14
  export * from './commands';
15
15
  export * from './integrations';
16
16
  export { ConfigSchema, AffinitySchema, BlacklistSchema, RelationshipSchema, ScheduleSchema, OtherVariablesSchema, NativeToolsSchema, XmlToolsSchema, OtherCommandsSchema, OtherSettingsSchema } from './schema';
17
- export declare const usage = "\n## \u66F4\u65B0\u65E5\u5FD7\n\n0.2.3-alpha.3\n- \u4FEE\u590D\u65E0\u6CD5\u9009\u62E9\u65E5\u7A0B\u6A21\u578B\u7684\u95EE\u9898\n\n0.2.3-alpha.2\n- \u4FEE\u590D\u597D\u611F\u5EA6\u66F4\u65B0\u65F6\u672A\u66F4\u65B0 chatCount \u7684\u95EE\u9898\n\n0.2.3-alpha.1\n- \u65B0\u589E XML \u5DE5\u5177\uFF0C\u89E3\u6790\u539F\u59CB\u8F93\u51FA\u4E2D\u7684 <poke id=\"\" /> \u6233\u4E00\u6233\u3001<emoji message_id=\"\" emoji_id=\"\" /> \u8868\u60C5\u56DE\u5E94\u3001<delete message_id=\"\" /> \u64A4\u56DE\u6D88\u606F\n- \u91CD\u6784\u597D\u611F\u5EA6\uFF0C\u4ECE\u4F9D\u8D56\u5916\u90E8\u6A21\u578B\u6539\u4E3A\u89E3\u6790\u539F\u59CB\u8F93\u51FA\u4E2D\u7684 <affinity delta=\"\" action=\"increase|decrease\" id=\"\" />\n";
17
+ export declare const usage = "\n## \u66F4\u65B0\u65E5\u5FD7\n\n0.2.3\n- OneBot \u534F\u8BAE\u65B0\u589E NapCat/LLBot \u72EC\u7ACB\u9009\u9879\uFF0C\u6309\u914D\u7F6E\u9009\u62E9\u534F\u8BAE\n\n0.2.3-alpha.4\n- \u4FEE\u590D\u65E5\u7A0B\u751F\u6210\u63D0\u793A\u8BCD\u4EBA\u8BBE\u6CE8\u5165\u53D8\u91CF {persona} \u5931\u6548\u7684\u95EE\u9898\uFF0C\u65B0\u589E\u6A21\u578B\u9009\u62E9\u4E0E\u4EBA\u8BBE\u6CE8\u5165\u9009\u9879\n- \u5929\u6C14\u670D\u52A1\u5207\u6362\u4E3A open-meteo\uFF0C\u4E0D\u518D\u9700\u8981\u63D0\u4F9B token\n\n0.2.3-alpha.3\n- \u4FEE\u590D\u65E0\u6CD5\u9009\u62E9\u65E5\u7A0B\u6A21\u578B\u7684\u95EE\u9898\n";
package/lib/index.js CHANGED
@@ -427,25 +427,25 @@ var AffinitySchema = import_koishi.Schema.object({
427
427
  characterPromptTemplate: import_koishi.Schema.string().role("textarea").default(
428
428
  `## \u52A8\u4F5C\u6307\u4EE4
429
429
  \u4F60\u53EF\u4EE5\u6839\u636E\u9700\u8981\u521B\u5EFA\u4E00\u4E2A\u72EC\u7ACB\u7684 \`<actions>\` \u5143\u7D20\u3002\u5B83\u7528\u4E8E\u6267\u884C\u975E\u8BED\u8A00\u7684\u7CFB\u7EDF\u6307\u4EE4\u3002\u5982\u679C\u4E0D\u9700\u8981\u6267\u884C\u4EFB\u4F55\u52A8\u4F5C\uFF0C\u8BF7\u7701\u7565\u6B64\u5143\u7D20\u3002
430
- 1. **\u6233\u4E00\u6233**: \`<poke id="user_id" />\`
431
- - **\u9002\u7528\u573A\u666F**:
432
- - \u5F53\u4F60\u60F3\u5F15\u8D77\u67D0\u4EBA\u7684\u6CE8\u610F\u65F6\u3002
433
- - \u5F53\u5BF9\u65B9\u8BF4\u4E86\u8BA9\u4F60\u611F\u5230\u65E0\u8BED\u3001\u65E0\u89C6\u4F60\u3001\u6216\u8005\u4F60\u60F3\u901A\u8FC7\u80A2\u4F53\u4E92\u52A8\u8C03\u4F83\u5BF9\u65B9\u65F6\u3002
434
- - \u4F5C\u4E3A\u4E00\u79CD\u4FCF\u76AE\u7684\u6253\u62DB\u547C\u65B9\u5F0F\u3002
435
- 2. **\u8868\u60C5\u56DE\u5E94**: \`<emoji message_id="message_id" emoji_id="emoji_id" />\`
436
- - \u7528\u4E8E\u5BF9\u4E0A\u4E0B\u6587\u4E2D\u7684\u7279\u5B9A\u6D88\u606F\u8FDB\u884C\u8868\u60C5\u56DE\u5E94\u3002
437
- - **emoji_id \u5BF9\u5E94\u8868**:
438
- - 424: \u8D5E\u540C (\u7EA2\u8272\u6309\u94AE)
439
- - 10068: \u95EE\u53F7
440
- - 265: \u9006\u5929 (\u5730\u94C1\u8001\u4EBA\u624B\u673A)
441
- - 76: \u70B9\u8D5E
442
- - 66: \u7231\u5FC3
443
- 3. **\u64A4\u56DE\u6D88\u606F**: \`<delete message_id="message_id" />\`
444
- - \u7528\u4E8E\u64A4\u56DE\u6307\u5B9A\u6D88\u606F\u3002
445
- 4. **\u597D\u611F\u5EA6\u66F4\u65B0**: \`<affinity delta="5" action="increase" id="user_id"/>\`
446
- - delta: \u597D\u611F\u5EA6\u53D8\u5316\u91CF\uFF08\u6B63\u6574\u6570\uFF09
447
- - action: increase \u6216 decrease
448
- - id: \u76EE\u6807\u7528\u6237 ID
430
+ 1. **\u6233\u4E00\u6233**: \`<poke id="user_id" />\`
431
+ - **\u9002\u7528\u573A\u666F**:
432
+ - \u5F53\u4F60\u60F3\u5F15\u8D77\u67D0\u4EBA\u7684\u6CE8\u610F\u65F6\u3002
433
+ - \u5F53\u5BF9\u65B9\u8BF4\u4E86\u8BA9\u4F60\u611F\u5230\u65E0\u8BED\u3001\u65E0\u89C6\u4F60\u3001\u6216\u8005\u4F60\u60F3\u901A\u8FC7\u80A2\u4F53\u4E92\u52A8\u8C03\u4F83\u5BF9\u65B9\u65F6\u3002
434
+ - \u4F5C\u4E3A\u4E00\u79CD\u4FCF\u76AE\u7684\u6253\u62DB\u547C\u65B9\u5F0F\u3002
435
+ 2. **\u8868\u60C5\u56DE\u5E94**: \`<emoji message_id="message_id" emoji_id="emoji_id" />\`
436
+ - \u7528\u4E8E\u5BF9\u4E0A\u4E0B\u6587\u4E2D\u7684\u7279\u5B9A\u6D88\u606F\u8FDB\u884C\u8868\u60C5\u56DE\u5E94\u3002
437
+ - **emoji_id \u5BF9\u5E94\u8868**:
438
+ - 424: \u8D5E\u540C (\u7EA2\u8272\u6309\u94AE)
439
+ - 10068: \u95EE\u53F7
440
+ - 265: \u9006\u5929 (\u5730\u94C1\u8001\u4EBA\u624B\u673A)
441
+ - 76: \u70B9\u8D5E
442
+ - 66: \u7231\u5FC3
443
+ 3. **\u64A4\u56DE\u6D88\u606F**: \`<delete message_id="message_id" />\`
444
+ - \u7528\u4E8E\u64A4\u56DE\u6307\u5B9A\u6D88\u606F\u3002
445
+ 4. **\u597D\u611F\u5EA6\u66F4\u65B0**: \`<affinity delta="5" action="increase" id="user_id"/>\`
446
+ - delta: \u597D\u611F\u5EA6\u53D8\u5316\u91CF\uFF08\u6B63\u6574\u6570\uFF09
447
+ - action: increase \u6216 decrease
448
+ - id: \u76EE\u6807\u7528\u6237 ID
449
449
 
450
450
  **\u683C\u5F0F\u793A\u4F8B**:
451
451
  \`\`\`xml
@@ -539,7 +539,14 @@ var import_koishi4 = require("koishi");
539
539
  var ScheduleSchema = import_koishi4.Schema.object({
540
540
  schedule: import_koishi4.Schema.object({
541
541
  enabled: import_koishi4.Schema.boolean().default(true).description("\u662F\u5426\u542F\u7528\u65E5\u7A0B\u529F\u80FD"),
542
- model: import_koishi4.Schema.dynamic("model").default("").description("\u65E5\u7A0B\u751F\u6210\u4F7F\u7528\u7684\u6A21\u578B\uFF0C\u7559\u7A7A\u5219\u4F7F\u7528 ChatLuna \u9ED8\u8BA4\u6A21\u578B"),
542
+ model: import_koishi4.Schema.dynamic("model").default("").description("\u65E5\u7A0B\u751F\u6210\u4F7F\u7528\u7684\u6A21\u578B"),
543
+ personaSource: import_koishi4.Schema.union([
544
+ import_koishi4.Schema.const("none").description("\u4E0D\u6CE8\u5165\u4EBA\u8BBE"),
545
+ import_koishi4.Schema.const("chatluna").description("\u4F7F\u7528 ChatLuna \u4E3B\u63D2\u4EF6\u4EBA\u8BBE"),
546
+ import_koishi4.Schema.const("custom").description("\u4F7F\u7528\u81EA\u5B9A\u4E49\u4EBA\u8BBE")
547
+ ]).default("none").description("\u4EBA\u8BBE\u6CE8\u5165\u6765\u6E90"),
548
+ personaChatlunaPreset: import_koishi4.Schema.dynamic("preset").default("\u65E0").hidden((_, cfg) => (cfg?.personaSource || "none") !== "chatluna").description("\u5F53\u9009\u62E9\u4E3B\u63D2\u4EF6\u9884\u8BBE\u65F6\uFF0C\u6307\u5B9A\u8981\u6CE8\u5165\u7684 ChatLuna \u9884\u8BBE"),
549
+ personaCustomPreset: import_koishi4.Schema.string().role("textarea").default("").hidden((_, cfg) => (cfg?.personaSource || "none") !== "custom").description("\u5F53\u9009\u62E9\u81EA\u5B9A\u4E49\u4EBA\u8BBE\u65F6\u6CE8\u5165\u7684\u6587\u672C\u5185\u5BB9"),
543
550
  variableName: import_koishi4.Schema.string().default("schedule").description("\u4ECA\u65E5\u65E5\u7A0B\u53D8\u91CF\u540D\u79F0"),
544
551
  currentVariableName: import_koishi4.Schema.string().default("currentSchedule").description("\u5F53\u524D\u65E5\u7A0B\u53D8\u91CF\u540D\u79F0"),
545
552
  outfitVariableName: import_koishi4.Schema.string().default("outfit").description("\u4ECA\u65E5\u7A7F\u642D\u53D8\u91CF\u540D\u79F0"),
@@ -553,6 +560,9 @@ var ScheduleSchema = import_koishi4.Schema.object({
553
560
  }).default({
554
561
  enabled: true,
555
562
  model: "",
563
+ personaSource: "none",
564
+ personaChatlunaPreset: "\u65E0",
565
+ personaCustomPreset: "",
556
566
  variableName: "schedule",
557
567
  currentVariableName: "currentSchedule",
558
568
  outfitVariableName: "outfit",
@@ -572,11 +582,6 @@ var WeatherSchema = import_koishi5.Schema.object({
572
582
  weather: import_koishi5.Schema.object({
573
583
  enabled: import_koishi5.Schema.boolean().default(false).description("\u662F\u5426\u542F\u7528\u5929\u6C14\u529F\u80FD"),
574
584
  variableName: import_koishi5.Schema.string().default("weather").description("\u5929\u6C14\u53D8\u91CF\u540D\u79F0"),
575
- apiToken: import_koishi5.Schema.string().role("secret").default("").description("ALAPI \u5929\u6C14 API Token\uFF08\u53EF\u5728 https://alapi.cn/dashboard/data/token \u83B7\u53D6\uFF09"),
576
- searchType: import_koishi5.Schema.union([
577
- import_koishi5.Schema.const("city").description("\u6309\u57CE\u5E02\u540D\u79F0"),
578
- import_koishi5.Schema.const("ip").description("\u6309\u5F53\u524D IP \u5B9A\u4F4D")
579
- ]).default("city").description("\u5929\u6C14\u641C\u7D22\u65B9\u5F0F"),
580
585
  cityName: import_koishi5.Schema.string().default("").description("\u57CE\u5E02\u540D\u79F0\uFF08\u5982\uFF1A\u957F\u6C99\uFF09"),
581
586
  hourlyRefresh: import_koishi5.Schema.boolean().default(false).description("\u6BCF\u5C0F\u65F6\u5237\u65B0\u5929\u6C14\u6570\u636E\uFF08\u5173\u95ED\u5219\u6BCF\u5929\u5237\u65B0\u4E00\u6B21\uFF09"),
582
587
  registerTool: import_koishi5.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u5DE5\u5177\uFF1A\u83B7\u53D6\u5929\u6C14"),
@@ -584,8 +589,6 @@ var WeatherSchema = import_koishi5.Schema.object({
584
589
  }).default({
585
590
  enabled: false,
586
591
  variableName: "weather",
587
- apiToken: "",
588
- searchType: "city",
589
592
  cityName: "",
590
593
  hourlyRefresh: false,
591
594
  registerTool: false,
@@ -656,6 +659,8 @@ var OtherVariablesSchema = import_koishi6.Schema.object({
656
659
  // src/schema/tools.ts
657
660
  var import_koishi7 = require("koishi");
658
661
  var NativeToolsSchema = import_koishi7.Schema.object({
662
+ enableNapCatProtocol: import_koishi7.Schema.boolean().default(true).description("\u542F\u7528 NapCat OneBot \u534F\u8BAE\uFF08\u4E0E LLBot \u4E8C\u9009\u4E00\uFF09"),
663
+ enableLlbotProtocol: import_koishi7.Schema.boolean().default(false).description("\u542F\u7528 LLBot OneBot \u534F\u8BAE\uFF08\u4E0E NapCat \u4E8C\u9009\u4E00\uFF09"),
659
664
  enablePokeTool: import_koishi7.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u5DE5\u5177\uFF1A\u6233\u4E00\u6233"),
660
665
  pokeToolName: import_koishi7.Schema.string().default("poke_user").description("ChatLuna \u5DE5\u5177\u540D\u79F0\uFF1A\u6233\u4E00\u6233"),
661
666
  enableSetSelfProfileTool: import_koishi7.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u5DE5\u5177\uFF1A\u4FEE\u6539\u81EA\u8EAB\u8D26\u6237\u4FE1\u606F"),
@@ -700,8 +705,10 @@ var NativeToolsSchema = import_koishi7.Schema.object({
700
705
  }).description("\u539F\u751F\u5DE5\u5177");
701
706
  var XmlToolsSchema = import_koishi7.Schema.object({
702
707
  enablePokeXmlTool: import_koishi7.Schema.boolean().default(false).description('\u542F\u7528 XML \u5F62\u5F0F\u7684\u6233\u4E00\u6233\u8C03\u7528\uFF08\u89E3\u6790 &lt;poke id=""/&gt;\uFF09'),
703
- enableEmojiXmlTool: import_koishi7.Schema.boolean().default(false).description('\u542F\u7528 XML \u5F62\u5F0F\u7684\u6D88\u606F\u8868\u60C5\u8C03\u7528\uFF08\u89E3\u6790 &lt;emoji message_id="" emoji_id=""/&gt;\uFF09'),
704
- enableDeleteXmlTool: import_koishi7.Schema.boolean().default(false).description('\u542F\u7528 XML \u5F62\u5F0F\u7684\u6D88\u606F\u64A4\u56DE\u8C03\u7528\uFF08\u89E3\u6790 &lt;delete message_id=""/&gt;\uFF09')
708
+ enableEmojiXmlTool: import_koishi7.Schema.boolean().default(false).description(
709
+ '\u542F\u7528 XML \u5F62\u5F0F\u7684\u6D88\u606F\u8868\u60C5\u8C03\u7528\uFF08\u89E3\u6790 &lt;emoji message_id="" emoji_id=""/&gt;\uFF0C\u9700 chatluna-character \u5F00\u542F enableMessageId\uFF0C\u53EF\u7528\u8868\u60C5 ID \u89C1 https://bot.q.qq.com/wiki/develop/gosdk/model/emoji \uFF09'
710
+ ),
711
+ enableDeleteXmlTool: import_koishi7.Schema.boolean().default(false).description('\u542F\u7528 XML \u5F62\u5F0F\u7684\u6D88\u606F\u64A4\u56DE\u8C03\u7528\uFF08\u89E3\u6790 &lt;delete message_id=""/&gt;\uFF0C\u9700 chatluna-character \u5F00\u542F enableMessageId\uFF09')
705
712
  }).description("XML \u5DE5\u5177");
706
713
  var OtherCommandsSchema = import_koishi7.Schema.object({
707
714
  groupListRenderAsImage: import_koishi7.Schema.boolean().default(false).description("\u5C06\u7FA4\u804A\u5217\u8868\u6E32\u67D3\u4E3A\u56FE\u7247\uFF08affinity.groupList\uFF09"),
@@ -7003,66 +7010,83 @@ function createWeatherProvider(deps) {
7003
7010
  }
7004
7011
 
7005
7012
  // src/services/weather/api.ts
7006
- var API_BASE_URL = "https://v3.alapi.cn/api/tianqi";
7007
- function findCurrentHourWeather(hours, timezone) {
7008
- if (!hours || !hours.length) return null;
7009
- const now = /* @__PURE__ */ new Date();
7010
- const formatter = new Intl.DateTimeFormat("zh-CN", {
7011
- timeZone: timezone,
7012
- year: "numeric",
7013
- month: "2-digit",
7014
- day: "2-digit",
7015
- hour: "2-digit",
7016
- hour12: false
7017
- });
7018
- const parts = formatter.formatToParts(now);
7019
- const year = parts.find((p) => p.type === "year")?.value;
7020
- const month = parts.find((p) => p.type === "month")?.value;
7021
- const day = parts.find((p) => p.type === "day")?.value;
7022
- const hour = parts.find((p) => p.type === "hour")?.value;
7023
- const currentHourStr = `${year}-${month}-${day} ${hour}:00:00`;
7024
- const exactMatch = hours.find((h15) => h15.time === currentHourStr);
7025
- if (exactMatch) return exactMatch;
7026
- const currentHourNum = parseInt(hour || "0", 10);
7027
- const currentDateStr = `${year}-${month}-${day}`;
7028
- for (const h15 of hours) {
7029
- if (!h15.time.startsWith(currentDateStr)) continue;
7030
- const hourMatch = h15.time.match(/(\d{2}):\d{2}:\d{2}$/);
7031
- if (!hourMatch) continue;
7032
- const hourNum = parseInt(hourMatch[1], 10);
7033
- if (hourNum === currentHourNum) return h15;
7034
- }
7035
- return hours[0];
7036
- }
7037
- function formatCurrentWeather(data, hourData, timezone) {
7038
- const now = /* @__PURE__ */ new Date();
7013
+ var GEO_API_BASE_URL = "https://geocoding-api.open-meteo.com/v1/search";
7014
+ var FORECAST_API_BASE_URL = "https://api.open-meteo.com/v1/forecast";
7015
+ var MAX_RETRY = 3;
7016
+ var wait = (ms) => new Promise((resolve2) => {
7017
+ setTimeout(resolve2, ms);
7018
+ });
7019
+ var WEATHER_CODE_MAP = {
7020
+ 0: "\u6674",
7021
+ 1: "\u591A\u4E91",
7022
+ 2: "\u591A\u4E91",
7023
+ 3: "\u9634",
7024
+ 45: "\u6709\u96FE",
7025
+ 48: "\u96FE\u51BB",
7026
+ 51: "\u5C0F\u96E8",
7027
+ 53: "\u4E2D\u96E8",
7028
+ 55: "\u5927\u96E8",
7029
+ 56: "\u5C0F\u96E8",
7030
+ 57: "\u4E2D\u96E8",
7031
+ 61: "\u5C0F\u96E8",
7032
+ 63: "\u4E2D\u96E8",
7033
+ 65: "\u5927\u96E8",
7034
+ 66: "\u51BB\u96E8",
7035
+ 67: "\u51BB\u96E8",
7036
+ 71: "\u5C0F\u96EA",
7037
+ 73: "\u4E2D\u96EA",
7038
+ 75: "\u5927\u96EA",
7039
+ 77: "\u96EA\u7C92",
7040
+ 80: "\u9635\u96E8",
7041
+ 81: "\u9635\u96E8",
7042
+ 82: "\u66B4\u96E8",
7043
+ 85: "\u9635\u96EA",
7044
+ 86: "\u9635\u96EA",
7045
+ 95: "\u96F7\u9635\u96E8",
7046
+ 96: "\u96F7\u9635\u96E8",
7047
+ 99: "\u96F7\u9635\u96E8"
7048
+ };
7049
+ var formatTemp = (value) => {
7050
+ if (!Number.isFinite(value)) return "";
7051
+ return Number.isInteger(value) ? `${value}` : `${Number(value.toFixed(1))}`;
7052
+ };
7053
+ var resolveWeatherText = (code) => {
7054
+ if (code === void 0 || code === null) return "";
7055
+ return WEATHER_CODE_MAP[code] || "\u672A\u77E5";
7056
+ };
7057
+ var formatCurrentWeather = (data, geo, current, daily, timezone) => {
7058
+ const now = new Date(current.time);
7039
7059
  const timeFormatter = new Intl.DateTimeFormat("zh-CN", {
7040
7060
  timeZone: timezone,
7041
7061
  hour: "2-digit",
7042
7062
  minute: "2-digit",
7043
7063
  hour12: false
7044
7064
  });
7065
+ const minTemp = daily?.temperature_2m_min?.[0];
7066
+ const maxTemp = daily?.temperature_2m_max?.[0];
7067
+ const weatherText = resolveWeatherText(current.weather_code);
7068
+ const windSpeed = current.wind_speed_10m ?? 0;
7045
7069
  return {
7046
- city: data.city,
7047
- province: data.province,
7048
- date: data.date,
7070
+ city: geo.name,
7071
+ province: geo.admin1 || geo.country || "",
7072
+ date: current.time.slice(0, 10),
7049
7073
  time: timeFormatter.format(now),
7050
- weather: hourData?.wea || data.weather,
7051
- temp: hourData?.temp ?? data.temp,
7052
- minTemp: data.min_temp,
7053
- maxTemp: data.max_temp,
7054
- wind: hourData?.wind || data.wind,
7055
- windLevel: hourData?.wind_level || data.wind_power,
7056
- humidity: data.humidity,
7057
- airLevel: data.aqi?.air_level || "",
7058
- airTips: data.aqi?.air_tips || ""
7059
- };
7060
- }
7061
- function formatWeatherText(weather) {
7074
+ weather: weatherText,
7075
+ temp: current.temperature_2m,
7076
+ minTemp: minTemp ?? current.temperature_2m,
7077
+ maxTemp: maxTemp ?? current.temperature_2m,
7078
+ wind: "\u98CE\u901F",
7079
+ windLevel: `${formatTemp(windSpeed)} km/h`,
7080
+ humidity: `${current.relative_humidity_2m}%`,
7081
+ airLevel: "",
7082
+ airTips: ""
7083
+ };
7084
+ };
7085
+ var formatWeatherText = (weather) => {
7062
7086
  const lines = [
7063
7087
  `\u{1F4CD} ${weather.province} ${weather.city}`,
7064
7088
  `\u{1F4C5} ${weather.date} ${weather.time}`,
7065
- `\u{1F324}\uFE0F ${weather.weather}\uFF0C${weather.temp}\xB0C\uFF08${weather.minTemp}~${weather.maxTemp}\xB0C\uFF09`,
7089
+ `\u{1F324}\uFE0F ${weather.weather}\uFF0C${formatTemp(weather.temp)}\xB0C\uFF08${formatTemp(weather.minTemp)}~${formatTemp(weather.maxTemp)}\xB0C\uFF09`,
7066
7090
  `\u{1F4A8} ${weather.wind} ${weather.windLevel}`,
7067
7091
  `\u{1F4A7} \u6E7F\u5EA6 ${weather.humidity}`
7068
7092
  ];
@@ -7070,20 +7094,16 @@ function formatWeatherText(weather) {
7070
7094
  lines.push(`\u{1F32B}\uFE0F \u7A7A\u6C14\u8D28\u91CF\uFF1A${weather.airLevel}`);
7071
7095
  }
7072
7096
  return lines.join("\n");
7073
- }
7097
+ };
7074
7098
  function createWeatherApi(deps) {
7075
7099
  const { ctx, weatherConfig, log } = deps;
7076
- const timezone = "Asia/Shanghai";
7100
+ const defaultTimezone = "Asia/Shanghai";
7077
7101
  const cache = /* @__PURE__ */ new Map();
7078
- const buildRequestParams = (options) => {
7079
- const params = {
7080
- token: weatherConfig.apiToken
7081
- };
7082
- const city = (options?.city || weatherConfig.cityName || "").trim();
7083
- if (city) params.city = city;
7084
- return params;
7102
+ const geoCache = /* @__PURE__ */ new Map();
7103
+ const formatCityKey = (options) => {
7104
+ return (options?.city || weatherConfig.cityName || "").trim();
7085
7105
  };
7086
- const buildCacheKey = (now, cityKey) => {
7106
+ const buildCacheKey = (now, cityKey, timezone) => {
7087
7107
  const formatter = new Intl.DateTimeFormat("zh-CN", {
7088
7108
  timeZone: timezone,
7089
7109
  year: "numeric",
@@ -7095,42 +7115,86 @@ function createWeatherApi(deps) {
7095
7115
  const timeKey = formatter.format(now).replace(/[\/\s:]/g, "-");
7096
7116
  return `${cityKey || "default"}-${timeKey}`;
7097
7117
  };
7098
- const fetchWeather = async (options) => {
7099
- if (!weatherConfig.enabled || !weatherConfig.apiToken) {
7118
+ const geocode = async (city, retryCount = 0) => {
7119
+ if (!city) return null;
7120
+ const cached = geoCache.get(city);
7121
+ const now = Date.now();
7122
+ if (cached && cached.expiresAt > now) return cached.result;
7123
+ try {
7124
+ const params = new URLSearchParams({
7125
+ name: city,
7126
+ count: "1",
7127
+ language: "zh",
7128
+ format: "json"
7129
+ });
7130
+ const url = `${GEO_API_BASE_URL}?${params.toString()}`;
7131
+ const response = await ctx.http.get(url);
7132
+ const result = response.results && response.results[0];
7133
+ if (!result) {
7134
+ log("warn", "\u672A\u627E\u5230\u57CE\u5E02\u7ECF\u7EAC\u5EA6", { city });
7135
+ return null;
7136
+ }
7137
+ geoCache.set(city, { result, expiresAt: now + 24 * 60 * 60 * 1e3 });
7138
+ return result;
7139
+ } catch (error) {
7140
+ if (retryCount < MAX_RETRY - 1) {
7141
+ log("warn", `\u5730\u7406\u7F16\u7801\u5931\u8D25\uFF0C${retryCount + 1}/${MAX_RETRY} \u6B21\u91CD\u8BD5\u4E2D...`, { city, error });
7142
+ await wait(2e3 * (retryCount + 1));
7143
+ return geocode(city, retryCount + 1);
7144
+ }
7145
+ log("warn", "\u5730\u7406\u7F16\u7801\u5931\u8D25\uFF0C\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8BD5\u6B21\u6570", { city, error });
7100
7146
  return null;
7101
7147
  }
7148
+ };
7149
+ const fetchWeather = async (options, retryCount = 0) => {
7150
+ if (!weatherConfig.enabled) return null;
7102
7151
  const now = /* @__PURE__ */ new Date();
7103
- const cityKey = (options?.city || weatherConfig.cityName || "").trim();
7152
+ const cityKey = formatCityKey(options);
7104
7153
  if (!cityKey) return null;
7105
- const currentKey = buildCacheKey(now, cityKey);
7154
+ const geo = await geocode(cityKey);
7155
+ if (!geo) return null;
7156
+ const timezone = geo.timezone || defaultTimezone;
7157
+ const currentKey = buildCacheKey(now, cityKey, timezone);
7106
7158
  if (cache.has(currentKey)) return cache.get(currentKey) || null;
7107
7159
  try {
7108
- const params = buildRequestParams(options);
7109
- if (!params.city) return null;
7110
- const queryString = new URLSearchParams(params).toString();
7111
- const url = `${API_BASE_URL}?${queryString}`;
7160
+ const params = new URLSearchParams({
7161
+ latitude: String(geo.latitude),
7162
+ longitude: String(geo.longitude),
7163
+ current: "temperature_2m,relative_humidity_2m,precipitation,weather_code,wind_speed_10m",
7164
+ daily: "weather_code,temperature_2m_max,temperature_2m_min",
7165
+ timezone
7166
+ });
7167
+ const url = `${FORECAST_API_BASE_URL}?${params.toString()}`;
7112
7168
  const response = await ctx.http.get(url);
7113
- if (!response.success || response.code !== 200 || !response.data) {
7114
- log("warn", "\u5929\u6C14 API \u8BF7\u6C42\u5931\u8D25", { message: response.message, code: response.code, city: params.city });
7169
+ const current = response?.current;
7170
+ const daily = response?.daily;
7171
+ if (!current) {
7172
+ log("warn", "\u5929\u6C14 API \u7F3A\u5C11\u5F53\u524D\u5929\u6C14\u6570\u636E", { city: cityKey });
7115
7173
  return cache.get(currentKey) || null;
7116
7174
  }
7117
- const data = response.data;
7118
- const hourData = findCurrentHourWeather(data.hour, timezone);
7119
- const current = formatCurrentWeather(data, hourData, timezone);
7175
+ const currentWeather = formatCurrentWeather(response, geo, current, daily, timezone);
7176
+ const weatherText = resolveWeatherText(current.weather_code);
7177
+ const minTemp = daily?.temperature_2m_min?.[0] ?? current.temperature_2m;
7178
+ const maxTemp = daily?.temperature_2m_max?.[0] ?? current.temperature_2m;
7120
7179
  const cachedData = {
7121
- current,
7122
- dailyWeather: data.weather,
7123
- hourlyWeather: hourData?.wea || data.weather,
7124
- dailyTemp: data.temp,
7125
- dailyMinTemp: data.min_temp,
7126
- dailyMaxTemp: data.max_temp,
7127
- hourlyTemp: hourData?.temp ?? data.temp
7180
+ current: currentWeather,
7181
+ dailyWeather: weatherText,
7182
+ hourlyWeather: weatherText,
7183
+ dailyTemp: current.temperature_2m,
7184
+ dailyMinTemp: minTemp,
7185
+ dailyMaxTemp: maxTemp,
7186
+ hourlyTemp: current.temperature_2m
7128
7187
  };
7129
7188
  cache.set(currentKey, cachedData);
7130
- log("debug", "\u5929\u6C14\u6570\u636E\u5DF2\u66F4\u65B0", { city: current.city, daily: cachedData.dailyWeather, hourly: cachedData.hourlyWeather });
7189
+ log("debug", "\u5929\u6C14\u6570\u636E\u5DF2\u66F4\u65B0", { city: currentWeather.city, daily: cachedData.dailyWeather, hourly: cachedData.hourlyWeather });
7131
7190
  return cachedData;
7132
7191
  } catch (error) {
7133
- log("warn", "\u83B7\u53D6\u5929\u6C14\u6570\u636E\u5931\u8D25", error);
7192
+ if (retryCount < MAX_RETRY - 1) {
7193
+ log("warn", `\u83B7\u53D6\u5929\u6C14\u6570\u636E\u5931\u8D25\uFF0C${retryCount + 1}/${MAX_RETRY} \u6B21\u91CD\u8BD5\u4E2D...`, error);
7194
+ await wait(2e3 * (retryCount + 1));
7195
+ return fetchWeather(options, retryCount + 1);
7196
+ }
7197
+ log("warn", "\u83B7\u53D6\u5929\u6C14\u6570\u636E\u5931\u8D25\uFF0C\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8BD5\u6B21\u6570", error);
7134
7198
  return cache.get(currentKey) || null;
7135
7199
  }
7136
7200
  };
@@ -7429,13 +7493,22 @@ async function callOneBotAPI(internal, action, params, fallbacks = []) {
7429
7493
  // src/integrations/onebot/tools/poke.ts
7430
7494
  async function sendPoke(params) {
7431
7495
  try {
7432
- const { session, userId, groupId, log } = params;
7496
+ const { session, userId, groupId, log, protocol } = params;
7433
7497
  const { error, internal, session: validatedSession } = ensureOneBotSession(session);
7434
7498
  if (error) return error;
7435
7499
  const resolvedGroupId = groupId?.trim() || validatedSession?.guildId || validatedSession?.channelId || validatedSession?.roomId;
7436
7500
  const payload = { user_id: userId };
7437
7501
  if (resolvedGroupId) payload.group_id = resolvedGroupId;
7438
- if (typeof internal._request === "function") {
7502
+ if (protocol === "llbot") {
7503
+ const action = payload.group_id ? "group_poke" : "friend_poke";
7504
+ if (typeof internal._request === "function") {
7505
+ await internal._request(action, payload);
7506
+ } else if (typeof internal[action] === "function") {
7507
+ await internal[action](payload);
7508
+ } else {
7509
+ throw new Error(`\u5F53\u524D\u9002\u914D\u5668\u672A\u5B9E\u73B0 ${action} API\u3002`);
7510
+ }
7511
+ } else if (typeof internal._request === "function") {
7439
7512
  await internal._request("send_poke", payload);
7440
7513
  } else if (typeof internal.sendPoke === "function") {
7441
7514
  await internal.sendPoke(
@@ -7457,7 +7530,7 @@ async function sendPoke(params) {
7457
7530
  }
7458
7531
  }
7459
7532
  function createPokeTool(deps) {
7460
- const { toolName, log } = deps;
7533
+ const { toolName, log, protocol } = deps;
7461
7534
  return new class extends import_tools8.StructuredTool {
7462
7535
  name = toolName || "poke_user";
7463
7536
  description = "Poke (nudge) a specified user in a group or private conversation.";
@@ -7469,7 +7542,7 @@ function createPokeTool(deps) {
7469
7542
  });
7470
7543
  async _call(input, _manager, runnable) {
7471
7544
  const session = getSession(runnable);
7472
- return sendPoke({ session, userId: input.userId, groupId: input.groupId, log });
7545
+ return sendPoke({ session, userId: input.userId, groupId: input.groupId, log, protocol });
7473
7546
  }
7474
7547
  }();
7475
7548
  }
@@ -7479,7 +7552,7 @@ var import_zod8 = require("zod");
7479
7552
  var import_tools9 = require("@langchain/core/tools");
7480
7553
  var genders = { unknown: "0", male: "1", female: "2" };
7481
7554
  function createSetProfileTool(deps) {
7482
- const { toolName, log } = deps;
7555
+ const { toolName, log, protocol } = deps;
7483
7556
  return new class extends import_tools9.StructuredTool {
7484
7557
  name = toolName || "set_self_profile";
7485
7558
  description = "Update the bot's own QQ profile (nickname, signature, gender).";
@@ -7495,7 +7568,7 @@ function createSetProfileTool(deps) {
7495
7568
  if (error) return error;
7496
7569
  const payload = { nickname: input.nickname };
7497
7570
  if (input.signature) payload.personal_note = input.signature;
7498
- if (input.gender) payload.sex = genders[input.gender];
7571
+ if (input.gender && protocol !== "llbot") payload.sex = genders[input.gender];
7499
7572
  await callOneBotAPI(internal, "set_qq_profile", payload, ["setQQProfile"]);
7500
7573
  const message = "\u673A\u5668\u4EBA\u8D44\u6599\u5DF2\u66F4\u65B0\u3002";
7501
7574
  log?.("info", message);
@@ -7555,9 +7628,12 @@ var import_zod10 = require("zod");
7555
7628
  var import_tools11 = require("@langchain/core/tools");
7556
7629
  async function sendMsgEmoji(params) {
7557
7630
  try {
7558
- const { session, messageId, emojiId, log } = params;
7631
+ const { session, messageId, emojiId, log, protocol } = params;
7559
7632
  if (!session) return "No session context available.";
7560
7633
  if (session.platform !== "onebot") return "This tool only supports OneBot platform.";
7634
+ if (protocol === "llbot" && !session.guildId && !session.channelId) {
7635
+ return "\u5F53\u524D\u4F1A\u8BDD\u4E0D\u662F\u7FA4\u804A\uFF0CLLBot \u4E0D\u652F\u6301\u79C1\u804A\u8868\u60C5\u56DE\u5E94\u3002";
7636
+ }
7561
7637
  const messageIdRaw = messageId.trim();
7562
7638
  const emojiIdRaw = emojiId.trim();
7563
7639
  if (!messageIdRaw) return "message_id is required.";
@@ -7580,7 +7656,7 @@ async function sendMsgEmoji(params) {
7580
7656
  }
7581
7657
  }
7582
7658
  function createSetMsgEmojiTool(deps) {
7583
- const { toolName, log } = deps;
7659
+ const { toolName, log, protocol } = deps;
7584
7660
  return new class extends import_tools11.StructuredTool {
7585
7661
  name = toolName || "set_msg_emoji";
7586
7662
  description = "React to a message with an emoji by messageId. Required: message_id and emoji_id (emoji ID).";
@@ -7590,7 +7666,7 @@ function createSetMsgEmojiTool(deps) {
7590
7666
  });
7591
7667
  async _call(input, _manager, runnable) {
7592
7668
  const session = getSession(runnable);
7593
- return sendMsgEmoji({ session, messageId: input.messageId, emojiId: input.emojiId, log });
7669
+ return sendMsgEmoji({ session, messageId: input.messageId, emojiId: input.emojiId, log, protocol });
7594
7670
  }
7595
7671
  }();
7596
7672
  }
@@ -7599,7 +7675,7 @@ function createSetMsgEmojiTool(deps) {
7599
7675
  var import_zod11 = require("zod");
7600
7676
  var import_tools12 = require("@langchain/core/tools");
7601
7677
  function createFakeMessageTool(deps) {
7602
- const { toolName, log } = deps;
7678
+ const { toolName, log, protocol } = deps;
7603
7679
  return new class extends import_tools12.StructuredTool {
7604
7680
  name = toolName || "send_fake_msg";
7605
7681
  description = "Forge messages for one or more users and send as a merged forward. Accepts messages array or senderId + texts. Requires OneBot and send_forward_msg support.";
@@ -7642,6 +7718,18 @@ function createFakeMessageTool(deps) {
7642
7718
  if (!targetGroupId) {
7643
7719
  return "Missing targetGroupId. Provide targetGroupId or run inside a group session.";
7644
7720
  }
7721
+ const buildForwardContent = (content) => [{
7722
+ type: "text",
7723
+ data: { text: content }
7724
+ }];
7725
+ const buildLegacyNodes = (targets) => targets.map((node) => ({
7726
+ type: "node",
7727
+ data: {
7728
+ name: node.data.name,
7729
+ uin: node.data.uin,
7730
+ content: node.data.content.map((segment) => segment.data.text || "").filter(Boolean).join("")
7731
+ }
7732
+ }));
7645
7733
  const nodes = (() => {
7646
7734
  const buildNodesFromMessages = (messages) => {
7647
7735
  return messages.map((item) => {
@@ -7656,7 +7744,7 @@ function createFakeMessageTool(deps) {
7656
7744
  data: {
7657
7745
  name: displayName2 || uin,
7658
7746
  uin,
7659
- content: text
7747
+ content: buildForwardContent(text)
7660
7748
  }
7661
7749
  };
7662
7750
  }).filter((v) => Boolean(v));
@@ -7688,7 +7776,7 @@ function createFakeMessageTool(deps) {
7688
7776
  data: {
7689
7777
  name: displayName,
7690
7778
  uin: senderId,
7691
- content
7779
+ content: buildForwardContent(content)
7692
7780
  }
7693
7781
  }));
7694
7782
  })();
@@ -7708,12 +7796,22 @@ function createFakeMessageTool(deps) {
7708
7796
  );
7709
7797
  const { error, internal } = ensureOneBotSession(session);
7710
7798
  if (error) return error;
7711
- await callOneBotAPI(
7712
- internal,
7713
- "send_forward_msg",
7714
- { group_id: targetGroupId, messages: nodes },
7715
- ["sendForwardMsg"]
7716
- );
7799
+ if (protocol === "llbot") {
7800
+ await callOneBotAPI(
7801
+ internal,
7802
+ "send_group_forward_msg",
7803
+ { group_id: targetGroupId, messages: nodes },
7804
+ ["sendGroupForwardMsg"]
7805
+ );
7806
+ } else {
7807
+ const legacyNodes = buildLegacyNodes(nodes);
7808
+ await callOneBotAPI(
7809
+ internal,
7810
+ "send_forward_msg",
7811
+ { group_id: targetGroupId, messages: legacyNodes },
7812
+ ["sendForwardMsg"]
7813
+ );
7814
+ }
7717
7815
  const senderSet = Array.from(new Set(nodes.map((n) => n.data.uin || n.data.name).filter(Boolean)));
7718
7816
  const senderLabel = senderSet.length ? senderSet.join(",") : "unknown";
7719
7817
  const success = `Forged ${nodes.length} messages from ${senderLabel} and forwarded to group ${targetGroupId}.`;
@@ -7731,7 +7829,7 @@ function createFakeMessageTool(deps) {
7731
7829
  var import_zod12 = require("zod");
7732
7830
  var import_tools13 = require("@langchain/core/tools");
7733
7831
  function createForwardMessageTool(deps) {
7734
- const { toolName, messageStore, log } = deps;
7832
+ const { toolName, messageStore, log, protocol } = deps;
7735
7833
  return new class extends import_tools13.StructuredTool {
7736
7834
  name = toolName || "send_forward_msg";
7737
7835
  description = "Forward messages as a merged forward to a group. messageIds is required to specify messages to forward. Requires message_id exposure via chatluna-character enableMessageId.";
@@ -7749,11 +7847,11 @@ function createForwardMessageTool(deps) {
7749
7847
  return "Missing targetGroupId. Provide targetGroupId or run inside a group session.";
7750
7848
  }
7751
7849
  const explicitIds = Array.isArray(input.messageIds) && input.messageIds.length ? input.messageIds.map((id) => id.trim()).filter(Boolean) : [];
7752
- let nodes;
7850
+ let legacyNodes;
7753
7851
  if (explicitIds.length > 0) {
7754
7852
  const found = messageStore.findByIds(session, explicitIds);
7755
7853
  const map = new Map(found.map((msg) => [msg.messageId, msg]));
7756
- nodes = explicitIds.map((id) => {
7854
+ legacyNodes = explicitIds.map((id) => {
7757
7855
  const hit = map.get(id);
7758
7856
  if (!hit) return null;
7759
7857
  return {
@@ -7761,11 +7859,11 @@ function createForwardMessageTool(deps) {
7761
7859
  data: {
7762
7860
  name: hit.username || hit.userId || "\u672A\u77E5\u7528\u6237",
7763
7861
  uin: hit.userId || session.userId || "",
7764
- content: hit.content
7862
+ content: String(hit.content || "")
7765
7863
  }
7766
7864
  };
7767
7865
  }).filter((item) => item !== null);
7768
- if (!nodes.length) {
7866
+ if (!legacyNodes.length) {
7769
7867
  return "No messages found for provided messageIds.";
7770
7868
  }
7771
7869
  } else {
@@ -7773,13 +7871,30 @@ function createForwardMessageTool(deps) {
7773
7871
  }
7774
7872
  const { error, internal } = ensureOneBotSession(session);
7775
7873
  if (error) return error;
7776
- await callOneBotAPI(
7777
- internal,
7778
- "send_forward_msg",
7779
- { group_id: targetGroupId, messages: nodes },
7780
- ["sendForwardMsg"]
7781
- );
7782
- const success = `Forwarded ${nodes.length} messages to group ${targetGroupId}.`;
7874
+ if (protocol === "llbot") {
7875
+ const llbotNodes = legacyNodes.map((node) => ({
7876
+ type: "node",
7877
+ data: {
7878
+ name: node.data.name,
7879
+ uin: node.data.uin,
7880
+ content: [{ type: "text", data: { text: node.data.content } }]
7881
+ }
7882
+ }));
7883
+ await callOneBotAPI(
7884
+ internal,
7885
+ "send_group_forward_msg",
7886
+ { group_id: targetGroupId, messages: llbotNodes },
7887
+ ["sendGroupForwardMsg"]
7888
+ );
7889
+ } else {
7890
+ await callOneBotAPI(
7891
+ internal,
7892
+ "send_forward_msg",
7893
+ { group_id: targetGroupId, messages: legacyNodes },
7894
+ ["sendForwardMsg"]
7895
+ );
7896
+ }
7897
+ const success = `Forwarded ${legacyNodes.length} messages to group ${targetGroupId}.`;
7783
7898
  log?.("info", success);
7784
7899
  return success;
7785
7900
  } catch (error) {
@@ -8473,7 +8588,7 @@ function resolveVariableNames(config) {
8473
8588
  "\u968F\u673A\u53D8\u91CF",
8474
8589
  config.random?.variableName || config.otherVariables?.random?.variableName || "random"
8475
8590
  );
8476
- if (config.weather?.enabled && config.weather?.apiToken) {
8591
+ if (config.weather?.enabled) {
8477
8592
  push("\u5929\u6C14\u53D8\u91CF", config.weather.variableName || "weather");
8478
8593
  }
8479
8594
  const scheduleConfig = config.schedule || {};
@@ -8500,7 +8615,7 @@ function resolveToolNames(config) {
8500
8615
  if (config.enablePokeTool) {
8501
8616
  tools.push(`\u6233\u4E00\u6233\u5DE5\u5177\uFF1A${(config.pokeToolName || "poke_user").trim()}`);
8502
8617
  }
8503
- if (config.weather?.enabled && config.weather?.apiToken && config.weather?.registerTool) {
8618
+ if (config.weather?.enabled && config.weather?.registerTool) {
8504
8619
  tools.push(`\u5929\u6C14\u5DE5\u5177\uFF1A${(config.weather.toolName || "get_weather").trim() || "get_weather"}`);
8505
8620
  }
8506
8621
  if (config.enableSetSelfProfileTool) {
@@ -8581,6 +8696,17 @@ function apply(ctx, config) {
8581
8696
  });
8582
8697
  });
8583
8698
  const log = createLogger2(ctx, config);
8699
+ const resolveOneBotProtocol = () => {
8700
+ if (config.enableNapCatProtocol && config.enableLlbotProtocol) {
8701
+ log("warn", "NapCat \u4E0E LLBot \u534F\u8BAE\u540C\u65F6\u542F\u7528\uFF0C\u5C06\u4F18\u5148\u4F7F\u7528 LLBot\u3002");
8702
+ return "llbot";
8703
+ }
8704
+ if (config.enableLlbotProtocol) return "llbot";
8705
+ if (config.enableNapCatProtocol) return "napcat";
8706
+ log("warn", "\u672A\u542F\u7528 OneBot \u534F\u8BAE\u9009\u9879\uFF0C\u9ED8\u8BA4\u4F7F\u7528 NapCat\u3002");
8707
+ return "napcat";
8708
+ };
8709
+ const onebotProtocol = resolveOneBotProtocol();
8584
8710
  log("warn", "\u26A0\uFE0F \u5347\u7EA7\u63D0\u793A\uFF1A0.2.1-alpha.10 \u7248\u672C\u540E\u6570\u636E\u5E93\u7ED3\u6784\u5DF2\u91CD\u6784\uFF0C\u82E5\u51FA\u73B0\u6570\u636E\u5E93\u76F8\u5173\u9519\u8BEF\uFF0C\u8BF7\u6267\u884C affinity.clearall \u547D\u4EE4\u6E05\u9664\u6570\u636E\u540E\u91CD\u8BD5\u3002\u597D\u611F\u5EA6\u5206\u6790\u63D0\u793A\u8BCD\u4E0E\u65E5\u7A0B\u751F\u6210\u63D0\u793A\u8BCD\u5DF2\u66F4\u65B0\uFF0C\u82E5\u60A8\u81EA\u5B9A\u4E49\u8FC7\u63D0\u793A\u8BCD\uFF0C\u8BF7\u5C06\u5176\u6062\u590D\u9ED8\u8BA4\u4EE5\u5E94\u7528\u6700\u65B0\u7248\u672C\u3002");
8585
8711
  const cache = createAffinityCache();
8586
8712
  const store = createAffinityStore({ ctx, config, log });
@@ -8636,12 +8762,35 @@ function apply(ctx, config) {
8636
8762
  toolName: "get_weather"
8637
8763
  };
8638
8764
  const weatherApi = createWeatherApi({ ctx, weatherConfig, log });
8765
+ const resolveSchedulePersonaPreset = (_session) => {
8766
+ const scheduleCfg = config.schedule || {};
8767
+ const source = scheduleCfg.personaSource || "none";
8768
+ const chatluna = ctx.chatluna;
8769
+ if (source === "chatluna") {
8770
+ let presetName = String(scheduleCfg.personaChatlunaPreset ?? "").trim();
8771
+ if (presetName === "\u65E0") presetName = "";
8772
+ if (presetName) {
8773
+ const presetRef = chatluna?.preset?.getPreset?.(presetName);
8774
+ const presetValue = presetRef?.value;
8775
+ if (typeof presetValue === "string") return presetValue;
8776
+ const rawText = presetValue?.rawText;
8777
+ if (typeof rawText === "string") return rawText;
8778
+ const configPrompt = presetValue?.config?.prompt;
8779
+ if (typeof configPrompt === "string") return configPrompt;
8780
+ }
8781
+ return chatluna?.personaPrompt || "";
8782
+ }
8783
+ if (source === "custom") {
8784
+ return String(scheduleCfg.personaCustomPreset ?? "").trim();
8785
+ }
8786
+ return "";
8787
+ };
8639
8788
  let scheduleModelRef;
8640
8789
  let defaultModelRef;
8641
8790
  const scheduleManager = createScheduleManager(ctx, config, {
8642
8791
  getModel: () => scheduleModelRef?.value ?? scheduleModelRef ?? defaultModelRef?.value ?? defaultModelRef ?? null,
8643
8792
  getMessageContent,
8644
- resolvePersonaPreset: () => "",
8793
+ resolvePersonaPreset: () => resolveSchedulePersonaPreset(),
8645
8794
  getWeatherText: () => weatherApi.getDailyWeather(),
8646
8795
  renderSchedule: renders.schedule,
8647
8796
  log
@@ -8736,7 +8885,7 @@ function apply(ctx, config) {
8736
8885
  const session = rawModelResponseSessionMap.get(rawModelResponseGuildId) || null;
8737
8886
  if (session && targetIds.length) {
8738
8887
  for (const userId of targetIds) {
8739
- void sendPoke({ session, userId, log });
8888
+ void sendPoke({ session, userId, log, protocol: onebotProtocol });
8740
8889
  }
8741
8890
  } else if (targetIds.length) {
8742
8891
  log("warn", "\u68C0\u6D4B\u5230\u6233\u4E00\u6233\u6807\u8BB0\u4F46\u7F3A\u5C11\u4F1A\u8BDD\u4E0A\u4E0B\u6587", {
@@ -8758,7 +8907,13 @@ function apply(ctx, config) {
8758
8907
  const messageId = String(match[1] || "").trim();
8759
8908
  const emojiId = String(match[2] || "").trim();
8760
8909
  if (messageId && emojiId) {
8761
- void sendMsgEmoji({ session, messageId, emojiId, log });
8910
+ void sendMsgEmoji({
8911
+ session,
8912
+ messageId,
8913
+ emojiId,
8914
+ log,
8915
+ protocol: onebotProtocol
8916
+ });
8762
8917
  }
8763
8918
  }
8764
8919
  } else {
@@ -8949,7 +9104,7 @@ function apply(ctx, config) {
8949
9104
  promptRenderer?.registerFunctionProvider?.(randomName, randomProvider);
8950
9105
  log("info", `\u968F\u673A\u6570\u53D8\u91CF\u5DF2\u6CE8\u518C: ${randomName}`);
8951
9106
  }
8952
- if (weatherConfig.enabled && weatherConfig.apiToken) {
9107
+ if (weatherConfig.enabled) {
8953
9108
  const weatherProvider = createWeatherProvider({ weatherApi });
8954
9109
  const weatherVariableName = String(weatherConfig.variableName || "weather").trim();
8955
9110
  if (weatherVariableName) {
@@ -8997,11 +9152,11 @@ function apply(ctx, config) {
8997
9152
  plugin.registerTool(toolName, {
8998
9153
  selector: () => true,
8999
9154
  authorization: (session) => session?.platform === "onebot",
9000
- createTool: () => createPokeTool({ ctx, toolName, log })
9155
+ createTool: () => createPokeTool({ ctx, toolName, log, protocol: onebotProtocol })
9001
9156
  });
9002
9157
  log("info", `\u6233\u4E00\u6233\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
9003
9158
  }
9004
- if (weatherConfig.enabled && weatherConfig.apiToken && weatherConfig.registerTool) {
9159
+ if (weatherConfig.enabled && weatherConfig.registerTool) {
9005
9160
  const weatherToolName = String(weatherConfig.toolName || "get_weather").trim() || "get_weather";
9006
9161
  plugin.registerTool(weatherToolName, {
9007
9162
  selector: () => true,
@@ -9014,7 +9169,7 @@ function apply(ctx, config) {
9014
9169
  plugin.registerTool(toolName, {
9015
9170
  selector: () => true,
9016
9171
  authorization: (session) => session?.platform === "onebot",
9017
- createTool: () => createSetProfileTool({ ctx, toolName, log })
9172
+ createTool: () => createSetProfileTool({ ctx, toolName, log, protocol: onebotProtocol })
9018
9173
  });
9019
9174
  log("info", `\u8BBE\u7F6E\u8D44\u6599\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
9020
9175
  }
@@ -9032,7 +9187,7 @@ function apply(ctx, config) {
9032
9187
  plugin.registerTool(toolName, {
9033
9188
  selector: () => true,
9034
9189
  authorization: (session) => session?.platform === "onebot",
9035
- createTool: () => createSetMsgEmojiTool({ toolName, log })
9190
+ createTool: () => createSetMsgEmojiTool({ toolName, log, protocol: onebotProtocol })
9036
9191
  });
9037
9192
  log("info", `\u6D88\u606F\u8868\u60C5\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
9038
9193
  }
@@ -9044,7 +9199,8 @@ function apply(ctx, config) {
9044
9199
  createTool: () => createForwardMessageTool({
9045
9200
  toolName,
9046
9201
  messageStore,
9047
- log
9202
+ log,
9203
+ protocol: onebotProtocol
9048
9204
  })
9049
9205
  });
9050
9206
  log("info", `\u5408\u5E76\u8F6C\u53D1\u6D88\u606F\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
@@ -9054,7 +9210,7 @@ function apply(ctx, config) {
9054
9210
  plugin.registerTool(toolName, {
9055
9211
  selector: () => true,
9056
9212
  authorization: (session) => session?.platform === "onebot",
9057
- createTool: () => createFakeMessageTool({ toolName, log })
9213
+ createTool: () => createFakeMessageTool({ toolName, log, protocol: onebotProtocol })
9058
9214
  });
9059
9215
  log("info", `\u4F2A\u9020\u6D88\u606F\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
9060
9216
  }
@@ -9087,15 +9243,15 @@ function apply(ctx, config) {
9087
9243
  var usage = `
9088
9244
  ## \u66F4\u65B0\u65E5\u5FD7
9089
9245
 
9090
- 0.2.3-alpha.3
9091
- - \u4FEE\u590D\u65E0\u6CD5\u9009\u62E9\u65E5\u7A0B\u6A21\u578B\u7684\u95EE\u9898
9246
+ 0.2.3
9247
+ - OneBot \u534F\u8BAE\u65B0\u589E NapCat/LLBot \u72EC\u7ACB\u9009\u9879\uFF0C\u6309\u914D\u7F6E\u9009\u62E9\u534F\u8BAE
9092
9248
 
9093
- 0.2.3-alpha.2
9094
- - \u4FEE\u590D\u597D\u611F\u5EA6\u66F4\u65B0\u65F6\u672A\u66F4\u65B0 chatCount \u7684\u95EE\u9898
9249
+ 0.2.3-alpha.4
9250
+ - \u4FEE\u590D\u65E5\u7A0B\u751F\u6210\u63D0\u793A\u8BCD\u4EBA\u8BBE\u6CE8\u5165\u53D8\u91CF {persona} \u5931\u6548\u7684\u95EE\u9898\uFF0C\u65B0\u589E\u6A21\u578B\u9009\u62E9\u4E0E\u4EBA\u8BBE\u6CE8\u5165\u9009\u9879
9251
+ - \u5929\u6C14\u670D\u52A1\u5207\u6362\u4E3A open-meteo\uFF0C\u4E0D\u518D\u9700\u8981\u63D0\u4F9B token
9095
9252
 
9096
- 0.2.3-alpha.1
9097
- - \u65B0\u589E XML \u5DE5\u5177\uFF0C\u89E3\u6790\u539F\u59CB\u8F93\u51FA\u4E2D\u7684 &lt;poke id="" /&gt; \u6233\u4E00\u6233\u3001&lt;emoji message_id="" emoji_id="" /&gt; \u8868\u60C5\u56DE\u5E94\u3001&lt;delete message_id="" /&gt; \u64A4\u56DE\u6D88\u606F
9098
- - \u91CD\u6784\u597D\u611F\u5EA6\uFF0C\u4ECE\u4F9D\u8D56\u5916\u90E8\u6A21\u578B\u6539\u4E3A\u89E3\u6790\u539F\u59CB\u8F93\u51FA\u4E2D\u7684 &lt;affinity delta="" action="increase|decrease" id="" /&gt;
9253
+ 0.2.3-alpha.3
9254
+ - \u4FEE\u590D\u65E0\u6CD5\u9009\u62E9\u65E5\u7A0B\u6A21\u578B\u7684\u95EE\u9898
9099
9255
  `;
9100
9256
  // Annotate the CommonJS export names for ESM import in node:
9101
9257
  0 && (module.exports = {
@@ -14,9 +14,9 @@ export declare function createScheduleTool(deps: ScheduleToolDeps): {
14
14
  schema: z.ZodObject<{
15
15
  query: z.ZodOptional<z.ZodEnum<["full", "current"]>>;
16
16
  }, "strip", z.ZodTypeAny, {
17
- query?: "full" | "current" | undefined;
17
+ query?: "current" | "full" | undefined;
18
18
  }, {
19
- query?: "full" | "current" | undefined;
19
+ query?: "current" | "full" | undefined;
20
20
  }>;
21
21
  _call(input: {
22
22
  query?: "full" | "current";
@@ -3,6 +3,7 @@
3
3
  * 提供 OneBot 平台 API 调用的辅助函数
4
4
  */
5
5
  import type { Session } from 'koishi';
6
+ export type OneBotProtocol = 'napcat' | 'llbot';
6
7
  export interface OneBotInternal {
7
8
  _request?: (action: string, params: Record<string, unknown>) => Promise<unknown>;
8
9
  [key: string]: unknown;
@@ -5,15 +5,18 @@
5
5
  import { z } from 'zod';
6
6
  import type { Context, Session } from 'koishi';
7
7
  import type { LogFn } from '../../../types';
8
+ import { type OneBotProtocol } from '../api';
8
9
  export interface PokeToolDeps {
9
10
  ctx: Context;
10
11
  toolName: string;
12
+ protocol: OneBotProtocol;
11
13
  log?: LogFn;
12
14
  }
13
15
  export interface SendPokeParams {
14
16
  session: Session | null;
15
17
  userId: string;
16
18
  groupId?: string;
19
+ protocol: OneBotProtocol;
17
20
  log?: LogFn;
18
21
  }
19
22
  export declare function sendPoke(params: SendPokeParams): Promise<string>;
@@ -5,9 +5,11 @@
5
5
  import { z } from 'zod';
6
6
  import type { Context } from 'koishi';
7
7
  import type { LogFn } from '../../../types';
8
+ import { type OneBotProtocol } from '../api';
8
9
  export interface ProfileToolDeps {
9
10
  ctx: Context;
10
11
  toolName: string;
12
+ protocol: OneBotProtocol;
11
13
  log?: LogFn;
12
14
  }
13
15
  export declare function createSetProfileTool(deps: ProfileToolDeps): {
@@ -4,8 +4,10 @@
4
4
  */
5
5
  import { z } from 'zod';
6
6
  import type { LogFn } from '../../../types';
7
+ import { type OneBotProtocol } from '../api';
7
8
  export interface FakeMessageToolDeps {
8
9
  toolName: string;
10
+ protocol: OneBotProtocol;
9
11
  log?: LogFn;
10
12
  }
11
13
  export declare function createFakeMessageTool(deps: FakeMessageToolDeps): {
@@ -5,9 +5,11 @@
5
5
  import { z } from 'zod';
6
6
  import type { LogFn } from '../../../types';
7
7
  import type { MessageStore } from '../../../services/message/store';
8
+ import { type OneBotProtocol } from '../api';
8
9
  export interface ForwardMessageToolDeps {
9
10
  toolName: string;
10
11
  messageStore: MessageStore;
12
+ protocol: OneBotProtocol;
11
13
  log?: LogFn;
12
14
  }
13
15
  export declare function createForwardMessageTool(deps: ForwardMessageToolDeps): {
@@ -5,14 +5,17 @@
5
5
  import { StructuredTool } from '@langchain/core/tools';
6
6
  import type { LogFn } from '../../../types';
7
7
  import type { Session } from 'koishi';
8
+ import { type OneBotProtocol } from '../api';
8
9
  export interface SetMsgEmojiToolDeps {
9
10
  toolName: string;
11
+ protocol: OneBotProtocol;
10
12
  log?: LogFn;
11
13
  }
12
14
  export interface SendMsgEmojiParams {
13
15
  session: Session | null;
14
16
  messageId: string;
15
17
  emojiId: string;
18
+ protocol: OneBotProtocol;
16
19
  log?: LogFn;
17
20
  }
18
21
  export declare function sendMsgEmoji(params: SendMsgEmojiParams): Promise<string>;
@@ -111,6 +111,9 @@ export declare const ConfigSchema: Schema<{
111
111
  schedule?: ({
112
112
  enabled?: boolean | null | undefined;
113
113
  model?: any;
114
+ personaSource?: "none" | "chatluna" | "custom" | null | undefined;
115
+ personaChatlunaPreset?: any;
116
+ personaCustomPreset?: string | null | undefined;
114
117
  variableName?: string | null | undefined;
115
118
  currentVariableName?: string | null | undefined;
116
119
  outfitVariableName?: string | null | undefined;
@@ -126,8 +129,6 @@ export declare const ConfigSchema: Schema<{
126
129
  weather?: ({
127
130
  enabled?: boolean | null | undefined;
128
131
  variableName?: string | null | undefined;
129
- apiToken?: string | null | undefined;
130
- searchType?: "city" | "ip" | null | undefined;
131
132
  cityName?: string | null | undefined;
132
133
  hourlyRefresh?: boolean | null | undefined;
133
134
  registerTool?: boolean | null | undefined;
@@ -154,6 +155,8 @@ export declare const ConfigSchema: Schema<{
154
155
  max?: number | null | undefined;
155
156
  } & import("cosmokit").Dict) | null | undefined;
156
157
  } & {
158
+ enableNapCatProtocol?: boolean | null | undefined;
159
+ enableLlbotProtocol?: boolean | null | undefined;
157
160
  enablePokeTool?: boolean | null | undefined;
158
161
  pokeToolName?: string | null | undefined;
159
162
  enableSetSelfProfileTool?: boolean | null | undefined;
@@ -306,6 +309,9 @@ export declare const ConfigSchema: Schema<{
306
309
  schedule: Schemastery.ObjectT<{
307
310
  enabled: Schema<boolean, boolean>;
308
311
  model: Schema<any, any>;
312
+ personaSource: Schema<"none" | "chatluna" | "custom", "none" | "chatluna" | "custom">;
313
+ personaChatlunaPreset: Schema<any, any>;
314
+ personaCustomPreset: Schema<string, string>;
309
315
  variableName: Schema<string, string>;
310
316
  currentVariableName: Schema<string, string>;
311
317
  outfitVariableName: Schema<string, string>;
@@ -321,8 +327,6 @@ export declare const ConfigSchema: Schema<{
321
327
  weather: Schemastery.ObjectT<{
322
328
  enabled: Schema<boolean, boolean>;
323
329
  variableName: Schema<string, string>;
324
- apiToken: Schema<string, string>;
325
- searchType: Schema<"city" | "ip", "city" | "ip">;
326
330
  cityName: Schema<string, string>;
327
331
  hourlyRefresh: Schema<boolean, boolean>;
328
332
  registerTool: Schema<boolean, boolean>;
@@ -349,6 +353,8 @@ export declare const ConfigSchema: Schema<{
349
353
  max: Schema<number, number>;
350
354
  }>;
351
355
  } & {
356
+ enableNapCatProtocol: boolean;
357
+ enableLlbotProtocol: boolean;
352
358
  enablePokeTool: boolean;
353
359
  pokeToolName: string;
354
360
  enableSetSelfProfileTool: boolean;
@@ -7,6 +7,9 @@ export declare const ScheduleSchema: Schema<Schemastery.ObjectS<{
7
7
  schedule: Schema<Schemastery.ObjectS<{
8
8
  enabled: Schema<boolean, boolean>;
9
9
  model: Schema<any, any>;
10
+ personaSource: Schema<"none" | "chatluna" | "custom", "none" | "chatluna" | "custom">;
11
+ personaChatlunaPreset: Schema<any, any>;
12
+ personaCustomPreset: Schema<string, string>;
10
13
  variableName: Schema<string, string>;
11
14
  currentVariableName: Schema<string, string>;
12
15
  outfitVariableName: Schema<string, string>;
@@ -20,6 +23,9 @@ export declare const ScheduleSchema: Schema<Schemastery.ObjectS<{
20
23
  }>, Schemastery.ObjectT<{
21
24
  enabled: Schema<boolean, boolean>;
22
25
  model: Schema<any, any>;
26
+ personaSource: Schema<"none" | "chatluna" | "custom", "none" | "chatluna" | "custom">;
27
+ personaChatlunaPreset: Schema<any, any>;
28
+ personaCustomPreset: Schema<string, string>;
23
29
  variableName: Schema<string, string>;
24
30
  currentVariableName: Schema<string, string>;
25
31
  outfitVariableName: Schema<string, string>;
@@ -35,6 +41,9 @@ export declare const ScheduleSchema: Schema<Schemastery.ObjectS<{
35
41
  schedule: Schema<Schemastery.ObjectS<{
36
42
  enabled: Schema<boolean, boolean>;
37
43
  model: Schema<any, any>;
44
+ personaSource: Schema<"none" | "chatluna" | "custom", "none" | "chatluna" | "custom">;
45
+ personaChatlunaPreset: Schema<any, any>;
46
+ personaCustomPreset: Schema<string, string>;
38
47
  variableName: Schema<string, string>;
39
48
  currentVariableName: Schema<string, string>;
40
49
  outfitVariableName: Schema<string, string>;
@@ -48,6 +57,9 @@ export declare const ScheduleSchema: Schema<Schemastery.ObjectS<{
48
57
  }>, Schemastery.ObjectT<{
49
58
  enabled: Schema<boolean, boolean>;
50
59
  model: Schema<any, any>;
60
+ personaSource: Schema<"none" | "chatluna" | "custom", "none" | "chatluna" | "custom">;
61
+ personaChatlunaPreset: Schema<any, any>;
62
+ personaCustomPreset: Schema<string, string>;
51
63
  variableName: Schema<string, string>;
52
64
  currentVariableName: Schema<string, string>;
53
65
  outfitVariableName: Schema<string, string>;
@@ -4,6 +4,8 @@
4
4
  */
5
5
  import { Schema } from 'koishi';
6
6
  export declare const NativeToolsSchema: Schema<Schemastery.ObjectS<{
7
+ enableNapCatProtocol: Schema<boolean, boolean>;
8
+ enableLlbotProtocol: Schema<boolean, boolean>;
7
9
  enablePokeTool: Schema<boolean, boolean>;
8
10
  pokeToolName: Schema<string, string>;
9
11
  enableSetSelfProfileTool: Schema<boolean, boolean>;
@@ -38,6 +40,8 @@ export declare const NativeToolsSchema: Schema<Schemastery.ObjectS<{
38
40
  panSouMaxResults: Schema<number, number>;
39
41
  }>>;
40
42
  }>, Schemastery.ObjectT<{
43
+ enableNapCatProtocol: Schema<boolean, boolean>;
44
+ enableLlbotProtocol: Schema<boolean, boolean>;
41
45
  enablePokeTool: Schema<boolean, boolean>;
42
46
  pokeToolName: Schema<string, string>;
43
47
  enableSetSelfProfileTool: Schema<boolean, boolean>;
@@ -7,8 +7,6 @@ export declare const WeatherSchema: Schema<Schemastery.ObjectS<{
7
7
  weather: Schema<Schemastery.ObjectS<{
8
8
  enabled: Schema<boolean, boolean>;
9
9
  variableName: Schema<string, string>;
10
- apiToken: Schema<string, string>;
11
- searchType: Schema<"city" | "ip", "city" | "ip">;
12
10
  cityName: Schema<string, string>;
13
11
  hourlyRefresh: Schema<boolean, boolean>;
14
12
  registerTool: Schema<boolean, boolean>;
@@ -16,8 +14,6 @@ export declare const WeatherSchema: Schema<Schemastery.ObjectS<{
16
14
  }>, Schemastery.ObjectT<{
17
15
  enabled: Schema<boolean, boolean>;
18
16
  variableName: Schema<string, string>;
19
- apiToken: Schema<string, string>;
20
- searchType: Schema<"city" | "ip", "city" | "ip">;
21
17
  cityName: Schema<string, string>;
22
18
  hourlyRefresh: Schema<boolean, boolean>;
23
19
  registerTool: Schema<boolean, boolean>;
@@ -27,8 +23,6 @@ export declare const WeatherSchema: Schema<Schemastery.ObjectS<{
27
23
  weather: Schema<Schemastery.ObjectS<{
28
24
  enabled: Schema<boolean, boolean>;
29
25
  variableName: Schema<string, string>;
30
- apiToken: Schema<string, string>;
31
- searchType: Schema<"city" | "ip", "city" | "ip">;
32
26
  cityName: Schema<string, string>;
33
27
  hourlyRefresh: Schema<boolean, boolean>;
34
28
  registerTool: Schema<boolean, boolean>;
@@ -36,8 +30,6 @@ export declare const WeatherSchema: Schema<Schemastery.ObjectS<{
36
30
  }>, Schemastery.ObjectT<{
37
31
  enabled: Schema<boolean, boolean>;
38
32
  variableName: Schema<string, string>;
39
- apiToken: Schema<string, string>;
40
- searchType: Schema<"city" | "ip", "city" | "ip">;
41
33
  cityName: Schema<string, string>;
42
34
  hourlyRefresh: Schema<boolean, boolean>;
43
35
  registerTool: Schema<boolean, boolean>;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ALAPI 天气 API 服务
2
+ * 天气 API 服务(open-meteo)
3
3
  * 提供天气数据获取和当前时段天气解析
4
4
  */
5
5
  import type { Context } from 'koishi';
@@ -28,6 +28,6 @@ export declare function createWeatherApi(deps: WeatherApiDeps): {
28
28
  getDailyWeather: (options?: WeatherQueryOptions) => Promise<string>;
29
29
  getHourlyWeather: (options?: WeatherQueryOptions) => Promise<string>;
30
30
  invalidateCache: () => void;
31
- fetchWeather: (options?: WeatherQueryOptions) => Promise<CachedWeatherData | null>;
31
+ fetchWeather: (options?: WeatherQueryOptions, retryCount?: number) => Promise<CachedWeatherData | null>;
32
32
  };
33
33
  export type WeatherApi = ReturnType<typeof createWeatherApi>;
@@ -119,6 +119,8 @@ export interface Config {
119
119
  userInfo: UserInfoConfig;
120
120
  botInfo: BotInfoConfig;
121
121
  groupInfo: GroupInfoConfig;
122
+ enableNapCatProtocol: boolean;
123
+ enableLlbotProtocol: boolean;
122
124
  enablePokeTool: boolean;
123
125
  pokeToolName: string;
124
126
  enablePokeXmlTool: boolean;
@@ -5,6 +5,9 @@
5
5
  export interface ScheduleConfig {
6
6
  enabled: boolean;
7
7
  model?: string;
8
+ personaSource?: 'none' | 'chatluna' | 'custom';
9
+ personaChatlunaPreset?: string;
10
+ personaCustomPreset?: string;
8
11
  variableName: string;
9
12
  currentVariableName: string;
10
13
  outfitVariableName: string;
@@ -1,71 +1,7 @@
1
1
  /**
2
2
  * 天气相关类型定义
3
- * 包含 ALAPI 天气 API 响应结构
3
+ * 定义天气数据结构与配置项
4
4
  */
5
- export interface WeatherHourData {
6
- time: string;
7
- temp: number;
8
- wea: string;
9
- wea_code: string;
10
- wind: string;
11
- wind_level: string;
12
- }
13
- export interface WeatherAqi {
14
- air: string;
15
- air_level: string;
16
- air_tips: string;
17
- pm25: string;
18
- pm10: string;
19
- co: string;
20
- no2: string;
21
- so2: string;
22
- o3: string;
23
- }
24
- export interface WeatherIndex {
25
- type: string;
26
- level: string;
27
- name: string;
28
- content: string;
29
- }
30
- export interface WeatherData {
31
- city: string;
32
- city_en: string;
33
- province: string;
34
- province_en: string;
35
- city_id: string;
36
- date: string;
37
- update_time: string;
38
- weather: string;
39
- weather_code: string;
40
- temp: number;
41
- min_temp: number;
42
- max_temp: number;
43
- wind: string;
44
- wind_speed: string;
45
- wind_power: string;
46
- rain: string;
47
- rain_24h: string;
48
- humidity: string;
49
- visibility: string;
50
- pressure: string;
51
- air: string;
52
- air_pm25: string;
53
- sunrise: string;
54
- sunset: string;
55
- aqi: WeatherAqi;
56
- index: WeatherIndex[];
57
- alarm: unknown[];
58
- hour: WeatherHourData[];
59
- }
60
- export interface WeatherApiResponse {
61
- request_id: string;
62
- success: boolean;
63
- message: string;
64
- code: number;
65
- data: WeatherData;
66
- time: number;
67
- usage: number;
68
- }
69
5
  export interface CurrentWeather {
70
6
  city: string;
71
7
  province: string;
@@ -84,8 +20,6 @@ export interface CurrentWeather {
84
20
  export interface WeatherConfig {
85
21
  enabled: boolean;
86
22
  variableName: string;
87
- apiToken: string;
88
- searchType: 'city' | 'ip';
89
23
  cityName: string;
90
24
  hourlyRefresh: boolean;
91
25
  registerTool?: boolean;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-chatluna-affinity",
3
3
  "description": "为 ChatLuna Character 提供更多变量及工具,例如 {好感度}、{关系}、{日程}、{天气}、{用户信息}、{机器人信息}、{群信息}等变量并提供对应的工具调用和低好感自动拉黑功能。",
4
- "version": "0.2.3-alpha.3",
4
+ "version": "0.2.3",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
package/readme.md CHANGED
@@ -110,6 +110,13 @@ MIT © 2024-present chatluna-affinity contributors
110
110
 
111
111
  ## 更新日志
112
112
 
113
+ 0.2.3
114
+ - OneBot 协议新增 NapCat/LLBot 独立选项,按配置选择协议
115
+
116
+ 0.2.3-alpha.4
117
+ - 修复日程生成提示词人设注入变量 {persona} 失效的问题,新增模型选择与人设注入选项
118
+ - 天气服务切换为 open-meteo,不再需要提供 token
119
+
113
120
  0.2.3-alpha.3
114
121
  - 修复无法选择日程模型的问题
115
122