@lemoncat7/dsh-partner 2.8.6 → 2.11.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/README.md +3 -1
- package/docs/THIRD_PARTY_LICENSES.md +67 -0
- package/docs/blobfox-manifest.json +109 -0
- package/docs/character-cards-and-renewal.md +23 -0
- package/docs/chat-delivery.md +25 -0
- package/docs/licenses/Apache-2.0.txt +202 -0
- package/docs/natural-conversation-port.md +58 -0
- package/docs/releases/2.10.0.md +14 -0
- package/docs/releases/2.10.1.md +12 -0
- package/docs/releases/2.11.0.md +9 -0
- package/docs/releases/2.11.1.md +9 -0
- package/docs/releases/2.11.2.md +7 -0
- package/docs/releases/2.11.3.md +11 -0
- package/docs/releases/2.11.4.md +7 -0
- package/docs/releases/2.11.5.md +7 -0
- package/docs/releases/2.11.6.md +9 -0
- package/docs/releases/2.9.0.md +13 -0
- package/docs/releases/2.9.1.md +11 -0
- package/docs/releases/2.9.2.md +11 -0
- package/docs/storage-read-performance.md +35 -0
- package/lib/agent-runtime.d.ts +8 -2
- package/lib/agent-runtime.d.ts.map +1 -1
- package/lib/agent-runtime.js +201 -50
- package/lib/agent-runtime.js.map +1 -1
- package/lib/api/features/stickers-api.d.ts +5 -0
- package/lib/api/features/stickers-api.d.ts.map +1 -0
- package/lib/api/features/stickers-api.js +35 -0
- package/lib/api/features/stickers-api.js.map +1 -0
- package/lib/api.d.ts +2 -0
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js +35 -1
- package/lib/api.js.map +1 -1
- package/lib/attachments/storage-admin.js +1 -1
- package/lib/attachments/storage-admin.js.map +1 -1
- package/lib/channel-message.d.ts +10 -0
- package/lib/channel-message.d.ts.map +1 -1
- package/lib/channel-message.js.map +1 -1
- package/lib/channels/delivery-policy.d.ts +3 -0
- package/lib/channels/delivery-policy.d.ts.map +1 -1
- package/lib/channels/delivery-policy.js +24 -3
- package/lib/channels/delivery-policy.js.map +1 -1
- package/lib/channels/manager.d.ts +8 -0
- package/lib/channels/manager.d.ts.map +1 -1
- package/lib/channels/manager.js +126 -12
- package/lib/channels/manager.js.map +1 -1
- package/lib/channels/notification-delivery.d.ts.map +1 -1
- package/lib/channels/notification-delivery.js +9 -5
- package/lib/channels/notification-delivery.js.map +1 -1
- package/lib/channels/outbound-media.js +1 -1
- package/lib/channels/outbound-media.js.map +1 -1
- package/lib/channels/reply-progress-controller.d.ts +1 -0
- package/lib/channels/reply-progress-controller.d.ts.map +1 -1
- package/lib/channels/reply-progress-controller.js +8 -0
- package/lib/channels/reply-progress-controller.js.map +1 -1
- package/lib/channels/weixin/connect.d.ts.map +1 -1
- package/lib/character/conversation-behavior.d.ts +10 -0
- package/lib/character/conversation-behavior.d.ts.map +1 -0
- package/lib/character/conversation-behavior.js +58 -0
- package/lib/character/conversation-behavior.js.map +1 -0
- package/lib/character/domain.d.ts +48 -0
- package/lib/character/domain.d.ts.map +1 -0
- package/lib/character/domain.js +107 -0
- package/lib/character/domain.js.map +1 -0
- package/lib/character/idle-contact.d.ts +35 -0
- package/lib/character/idle-contact.d.ts.map +1 -0
- package/lib/character/idle-contact.js +61 -0
- package/lib/character/idle-contact.js.map +1 -0
- package/lib/character/preview.d.ts +12 -0
- package/lib/character/preview.d.ts.map +1 -0
- package/lib/character/preview.js +66 -0
- package/lib/character/preview.js.map +1 -0
- package/lib/character/store.d.ts +8 -0
- package/lib/character/store.d.ts.map +1 -0
- package/lib/character/store.js +27 -0
- package/lib/character/store.js.map +1 -0
- package/lib/chat/conversation.d.ts +13 -0
- package/lib/chat/conversation.d.ts.map +1 -0
- package/lib/chat/conversation.js +36 -0
- package/lib/chat/conversation.js.map +1 -0
- package/lib/chat/protocol.d.ts +43 -0
- package/lib/chat/protocol.d.ts.map +1 -0
- package/lib/chat/protocol.js +71 -0
- package/lib/chat/protocol.js.map +1 -0
- package/lib/chat/sticker-builtins.d.ts +9 -0
- package/lib/chat/sticker-builtins.d.ts.map +1 -0
- package/lib/chat/sticker-builtins.js +243 -0
- package/lib/chat/sticker-builtins.js.map +1 -0
- package/lib/chat/sticker-import.d.ts +13 -0
- package/lib/chat/sticker-import.d.ts.map +1 -0
- package/lib/chat/sticker-import.js +27 -0
- package/lib/chat/sticker-import.js.map +1 -0
- package/lib/chat/stickers.d.ts +28 -0
- package/lib/chat/stickers.d.ts.map +1 -0
- package/lib/chat/stickers.js +113 -0
- package/lib/chat/stickers.js.map +1 -0
- package/lib/chat/tools.d.ts +7 -0
- package/lib/chat/tools.d.ts.map +1 -0
- package/lib/chat/tools.js +91 -0
- package/lib/chat/tools.js.map +1 -0
- package/lib/client-api.d.ts +4 -0
- package/lib/client-api.d.ts.map +1 -1
- package/lib/client-api.js.map +1 -1
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +3295 -2242
- package/lib/client.js.map +4 -4
- package/lib/collaboration/composition.d.ts +2 -0
- package/lib/collaboration/composition.d.ts.map +1 -1
- package/lib/collaboration/composition.js +5 -0
- package/lib/collaboration/composition.js.map +1 -1
- package/lib/companions/service.js +1 -0
- package/lib/companions/service.js.map +1 -1
- package/lib/companions/session-configuration.js +2 -2
- package/lib/companions/session-configuration.js.map +1 -1
- package/lib/concern-store.d.ts +1 -0
- package/lib/concern-store.d.ts.map +1 -1
- package/lib/concern-store.js +20 -7
- package/lib/concern-store.js.map +1 -1
- package/lib/context-renewal.d.ts +5 -0
- package/lib/context-renewal.d.ts.map +1 -0
- package/lib/context-renewal.js +30 -0
- package/lib/context-renewal.js.map +1 -0
- package/lib/daily-review.d.ts +9 -1
- package/lib/daily-review.d.ts.map +1 -1
- package/lib/daily-review.js +41 -12
- package/lib/daily-review.js.map +1 -1
- package/lib/domain.d.ts +8 -0
- package/lib/domain.d.ts.map +1 -1
- package/lib/domain.js +7 -1
- package/lib/domain.js.map +1 -1
- package/lib/execution/agent-support.d.ts.map +1 -1
- package/lib/execution/agent-support.js +7 -1
- package/lib/execution/agent-support.js.map +1 -1
- package/lib/heartbeat.d.ts +1 -0
- package/lib/heartbeat.d.ts.map +1 -1
- package/lib/heartbeat.js +14 -2
- package/lib/heartbeat.js.map +1 -1
- package/lib/history-search.d.ts +6 -0
- package/lib/history-search.d.ts.map +1 -0
- package/lib/history-search.js +51 -0
- package/lib/history-search.js.map +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -1
- package/lib/index.js.map +1 -1
- package/lib/memory-domain.d.ts +3 -0
- package/lib/memory-domain.d.ts.map +1 -1
- package/lib/memory-prompt-context.js +1 -0
- package/lib/memory-prompt-context.js.map +1 -1
- package/lib/memory-reflection.d.ts.map +1 -1
- package/lib/memory-reflection.js +7 -2
- package/lib/memory-reflection.js.map +1 -1
- package/lib/memory-store.d.ts +20 -1
- package/lib/memory-store.d.ts.map +1 -1
- package/lib/memory-store.js +78 -27
- package/lib/memory-store.js.map +1 -1
- package/lib/notifications/service.d.ts.map +1 -1
- package/lib/notifications/service.js +3 -1
- package/lib/notifications/service.js.map +1 -1
- package/lib/scheduler/final-reply.d.ts +2 -0
- package/lib/scheduler/final-reply.d.ts.map +1 -1
- package/lib/storage/sqlite-schema.d.ts +7 -0
- package/lib/storage/sqlite-schema.d.ts.map +1 -0
- package/lib/storage/sqlite-schema.js +36 -0
- package/lib/storage/sqlite-schema.js.map +1 -0
- package/lib/ui/character-editor.d.ts +9 -0
- package/lib/ui/character-editor.d.ts.map +1 -0
- package/lib/ui/character-editor.js +108 -0
- package/lib/ui/character-editor.js.map +1 -0
- package/lib/ui/character-memory-editor.d.ts +4 -0
- package/lib/ui/character-memory-editor.d.ts.map +1 -0
- package/lib/ui/character-memory-editor.js +50 -0
- package/lib/ui/character-memory-editor.js.map +1 -0
- package/lib/ui/character-stepper.d.ts +16 -0
- package/lib/ui/character-stepper.d.ts.map +1 -0
- package/lib/ui/character-stepper.js +42 -0
- package/lib/ui/character-stepper.js.map +1 -0
- package/lib/ui/companion-draft.d.ts +2 -0
- package/lib/ui/companion-draft.d.ts.map +1 -1
- package/lib/ui/companion-draft.js +1 -1
- package/lib/ui/companion-draft.js.map +1 -1
- package/lib/ui/identity-editor.d.ts.map +1 -1
- package/lib/ui/identity-editor.js +11 -3
- package/lib/ui/identity-editor.js.map +1 -1
- package/lib/ui/idle-contact-editor.d.ts +8 -0
- package/lib/ui/idle-contact-editor.d.ts.map +1 -0
- package/lib/ui/idle-contact-editor.js +17 -0
- package/lib/ui/idle-contact-editor.js.map +1 -0
- package/lib/ui/memory/automation-settings.d.ts.map +1 -1
- package/lib/ui/memory/automation-settings.js +9 -2
- package/lib/ui/memory/automation-settings.js.map +1 -1
- package/lib/ui/push-draft.d.ts +3 -3
- package/lib/ui/role-reference-data.d.ts +3 -0
- package/lib/ui/role-reference-data.d.ts.map +1 -0
- package/lib/ui/role-reference-data.js +4 -0
- package/lib/ui/role-reference-data.js.map +1 -0
- package/lib/ui/role-reference.d.ts +3 -0
- package/lib/ui/role-reference.d.ts.map +1 -0
- package/lib/ui/role-reference.js +10 -0
- package/lib/ui/role-reference.js.map +1 -0
- package/lib/ui/settings-sections.d.ts +14 -0
- package/lib/ui/settings-sections.d.ts.map +1 -0
- package/lib/ui/settings-sections.js +18 -0
- package/lib/ui/settings-sections.js.map +1 -0
- package/lib/ui/sticker-import.d.ts +7 -0
- package/lib/ui/sticker-import.d.ts.map +1 -0
- package/lib/ui/sticker-import.js +65 -0
- package/lib/ui/sticker-import.js.map +1 -0
- package/lib/ui/sticker-library.d.ts +5 -0
- package/lib/ui/sticker-library.d.ts.map +1 -0
- package/lib/ui/sticker-library.js +55 -0
- package/lib/ui/sticker-library.js.map +1 -0
- package/lib/ui/workspace-components.js +2 -2
- package/lib/ui/workspace-components.js.map +1 -1
- package/package.json +22 -2
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Browser-safe, versioned role configuration. Absent/disabled preserves legacy identity. */
|
|
2
|
+
export interface CharacterCard {
|
|
3
|
+
schemaVersion: 1;
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
/** Authoritative free-form role. Absent means adapt the legacy fields losslessly. */
|
|
6
|
+
roleText?: string;
|
|
7
|
+
chatStyle?: string;
|
|
8
|
+
segmentedReplies?: boolean;
|
|
9
|
+
stickersEnabled?: boolean;
|
|
10
|
+
identity: string;
|
|
11
|
+
motivation: string;
|
|
12
|
+
voice: string;
|
|
13
|
+
relationship: string;
|
|
14
|
+
greeting: string;
|
|
15
|
+
length: 'short' | 'balanced' | 'rich';
|
|
16
|
+
narration: boolean;
|
|
17
|
+
examples: Array<{
|
|
18
|
+
user: string;
|
|
19
|
+
assistant: string;
|
|
20
|
+
avoid?: string;
|
|
21
|
+
}>;
|
|
22
|
+
lore: Array<{
|
|
23
|
+
id: string;
|
|
24
|
+
title: string;
|
|
25
|
+
keywords: string[];
|
|
26
|
+
content: string;
|
|
27
|
+
enabled: boolean;
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
30
|
+
export interface CharacterState {
|
|
31
|
+
scene: string;
|
|
32
|
+
relationship: string;
|
|
33
|
+
facts: string[];
|
|
34
|
+
events: string[];
|
|
35
|
+
pins: string[];
|
|
36
|
+
updatedAt: number;
|
|
37
|
+
sourceTurnId?: string;
|
|
38
|
+
}
|
|
39
|
+
export declare function emptyCharacterCard(): CharacterCard;
|
|
40
|
+
export declare function emptyCharacterState(): CharacterState;
|
|
41
|
+
export declare function normalizeCharacterCard(value: unknown): CharacterCard;
|
|
42
|
+
/** One editable document, including old examples. Never inject both old and new voices. */
|
|
43
|
+
export declare function roleTextForCard(card: CharacterCard): string;
|
|
44
|
+
export declare function normalizeCharacterState(value: unknown): CharacterState;
|
|
45
|
+
export declare function renderCharacterCore(card: CharacterCard | undefined, surface?: string): string;
|
|
46
|
+
export declare function activatedLore(card: CharacterCard, query: string): CharacterCard['lore'];
|
|
47
|
+
export declare function renderCharacterContext(card: CharacterCard | undefined, query: string, state?: CharacterState): string;
|
|
48
|
+
//# sourceMappingURL=domain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../src/character/domain.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,CAAC,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,CAAA;IACrC,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpE,IAAI,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CAClG;AACD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AACD,wBAAgB,kBAAkB,IAAI,aAAa,CAElD;AACD,wBAAgB,mBAAmB,IAAI,cAAc,CAA0F;AAe/I,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAuBpE;AAED,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAU3D;AACD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAMtE;AACD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,EAAE,OAAO,SAAiB,GAAG,MAAM,CAUrG;AACD,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAQvF;AACD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,cAAc,GAAG,MAAM,CAOrH"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
export function emptyCharacterCard() {
|
|
2
|
+
return { schemaVersion: 1, enabled: false, identity: '', motivation: '', voice: '', relationship: '', greeting: '', length: 'balanced', narration: false, examples: [], lore: [] };
|
|
3
|
+
}
|
|
4
|
+
export function emptyCharacterState() { return { scene: '', relationship: '', facts: [], events: [], pins: [], updatedAt: 0 }; }
|
|
5
|
+
function record(value) {
|
|
6
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
7
|
+
throw new Error('人格配置必须是对象');
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
function str(value, label, max) {
|
|
11
|
+
if (value === undefined)
|
|
12
|
+
return '';
|
|
13
|
+
if (typeof value !== 'string' || value.length > max)
|
|
14
|
+
throw new Error(`${label}最多 ${max} 字`);
|
|
15
|
+
return value.trim();
|
|
16
|
+
}
|
|
17
|
+
function list(value, label, max) {
|
|
18
|
+
if (value === undefined)
|
|
19
|
+
return [];
|
|
20
|
+
if (!Array.isArray(value) || value.length > max)
|
|
21
|
+
throw new Error(`${label}最多 ${max} 条`);
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
export function normalizeCharacterCard(value) {
|
|
25
|
+
const v = record(value);
|
|
26
|
+
if (v.schemaVersion !== undefined && v.schemaVersion !== 1)
|
|
27
|
+
throw new Error('不支持的人格卡版本');
|
|
28
|
+
if (typeof v.enabled !== 'boolean')
|
|
29
|
+
throw new Error('请选择是否启用人格强化');
|
|
30
|
+
const card = {
|
|
31
|
+
schemaVersion: 1, enabled: v.enabled,
|
|
32
|
+
...(v.segmentedReplies !== undefined ? { segmentedReplies: v.segmentedReplies === true } : {}),
|
|
33
|
+
...(v.stickersEnabled !== undefined ? { stickersEnabled: v.stickersEnabled === true } : {}),
|
|
34
|
+
...(v.roleText !== undefined ? { roleText: str(v.roleText, '角色设定', 48000) } : {}),
|
|
35
|
+
...(v.chatStyle !== undefined ? { chatStyle: str(v.chatStyle, '聊天偏好', 2000) } : {}),
|
|
36
|
+
identity: str(v.identity, '角色核心', 2000), motivation: str(v.motivation, '行为动机', 3000), voice: str(v.voice, '语言风格', 1500),
|
|
37
|
+
relationship: str(v.relationship, '关系起点', 1000), greeting: str(v.greeting, '开场白', 1000),
|
|
38
|
+
length: v.length === 'short' || v.length === 'rich' ? v.length : 'balanced', narration: v.narration === true,
|
|
39
|
+
examples: list(v.examples, '对话示例', 8).map(x => { const e = record(x); return { user: str(e.user, '示例用户发言', 1000), assistant: str(e.assistant, '示例回复', 1500), ...(e.avoid !== undefined ? { avoid: str(e.avoid, '示例反面回复', 1500) } : {}) }; }),
|
|
40
|
+
lore: list(v.lore, '世界条目', 40).map((x, i) => {
|
|
41
|
+
const e = record(x);
|
|
42
|
+
return {
|
|
43
|
+
id: str(e.id, '条目标识', 80) || `lore-${i + 1}`, title: str(e.title, '条目标题', 100), content: str(e.content, '世界设定', 2000),
|
|
44
|
+
keywords: list(e.keywords, '关键词', 8).map(x => str(x, '关键词', 80)).filter(Boolean), enabled: e.enabled !== false,
|
|
45
|
+
};
|
|
46
|
+
}),
|
|
47
|
+
};
|
|
48
|
+
if (new Set(card.lore.map(x => x.id)).size !== card.lore.length)
|
|
49
|
+
throw new Error('世界条目标识不能重复');
|
|
50
|
+
if (card.lore.some(x => x.enabled && (!x.content || !x.keywords.length)))
|
|
51
|
+
throw new Error('启用的世界条目需要内容与关键词');
|
|
52
|
+
if (card.enabled && !roleTextForCard(card))
|
|
53
|
+
throw new Error('请写下角色设定,几条身份和说话习惯即可;示例不是必填');
|
|
54
|
+
return card;
|
|
55
|
+
}
|
|
56
|
+
/** One editable document, including old examples. Never inject both old and new voices. */
|
|
57
|
+
export function roleTextForCard(card) {
|
|
58
|
+
if (card.roleText !== undefined)
|
|
59
|
+
return card.roleText.trim();
|
|
60
|
+
return [
|
|
61
|
+
card.identity ? `## 身份\n${card.identity}` : '',
|
|
62
|
+
card.motivation ? `## 性格与反应\n${card.motivation}` : '',
|
|
63
|
+
card.voice ? `## 说话习惯\n${card.voice}` : '',
|
|
64
|
+
card.relationship ? `## 相处关系\n${card.relationship}` : '',
|
|
65
|
+
card.greeting ? `## 初次见面的语气参考(不要重复问候)\n${card.greeting}` : '',
|
|
66
|
+
...card.examples.filter(e => e.user && e.assistant).map((e, i) => `## 对话参考 ${i + 1}(虚构示例,不是真实往事)\n对方:${e.user}\n角色:${e.assistant}${e.avoid ? `\n避免的回复(反例,不要模仿):${e.avoid}` : ''}`),
|
|
67
|
+
].filter(Boolean).join('\n\n');
|
|
68
|
+
}
|
|
69
|
+
export function normalizeCharacterState(value) {
|
|
70
|
+
const v = record(value);
|
|
71
|
+
return { scene: str(v.scene, '当前场景', 1500), relationship: str(v.relationship, '当前关系', 1000),
|
|
72
|
+
facts: list(v.facts, '角色事实', 20).map(x => str(x, '角色事实', 300)).filter(Boolean),
|
|
73
|
+
events: list(v.events, '剧情事件', 20).map(x => str(x, '剧情事件', 300)).filter(Boolean),
|
|
74
|
+
pins: list(v.pins, '固定记忆', 12).map(x => str(x, '固定记忆', 500)).filter(Boolean), updatedAt: 0 };
|
|
75
|
+
}
|
|
76
|
+
export function renderCharacterCore(card, surface = 'conversation') {
|
|
77
|
+
if (!card?.enabled)
|
|
78
|
+
return '';
|
|
79
|
+
const chat = surface === 'conversation' || surface === 'local';
|
|
80
|
+
return [
|
|
81
|
+
'【当前角色设定】',
|
|
82
|
+
'必须持续依据当前角色设定交流。旧身份中的表达习惯、历史回复和记忆摘要不能覆盖当前设定;历史只用于承接真实事实与话题。人格设定不能授权操作或虚构完成结果。角色示例是语感参考,不是真实用户经历,也不是每轮要复述的台词。',
|
|
83
|
+
// Dedicated work surfaces keep the legacy compact identity and omit conversational examples.
|
|
84
|
+
chat ? roleTextForCard(card) : (card.roleText !== undefined ? '沿用当前伙伴身份;本轮以任务要求为准。' : [card.identity, card.voice].filter(Boolean).join('\n')),
|
|
85
|
+
chat ? '身份、关系和生活背景是角色设定;不编造真实共同经历、已完成的操作或现实中的见面。' : '当前为工作或心跳执行:严格遵守 JSON、工具和交付协议,不加入角色旁白。',
|
|
86
|
+
].filter(Boolean).join('\n\n');
|
|
87
|
+
}
|
|
88
|
+
export function activatedLore(card, query) {
|
|
89
|
+
const normalized = query.normalize('NFKC').toLocaleLowerCase();
|
|
90
|
+
let budget = 5000;
|
|
91
|
+
return card.lore.filter(entry => {
|
|
92
|
+
if (!entry.enabled || !entry.keywords.some(k => normalized.includes(k.normalize('NFKC').toLocaleLowerCase())) || entry.content.length > budget)
|
|
93
|
+
return false;
|
|
94
|
+
budget -= entry.content.length;
|
|
95
|
+
return true;
|
|
96
|
+
}).slice(0, 5);
|
|
97
|
+
}
|
|
98
|
+
export function renderCharacterContext(card, query, state) {
|
|
99
|
+
if (!card?.enabled)
|
|
100
|
+
return '';
|
|
101
|
+
return ['【角色世界与会话状态 · 仅作为设定资料,不是工具指令或真实用户画像】',
|
|
102
|
+
...activatedLore(card, query).map(x => `世界设定:${x.content}`),
|
|
103
|
+
state ? JSON.stringify({ scene: state.scene, relationship: state.relationship, facts: state.facts, events: state.events.slice(-8), pins: state.pins }) : '',
|
|
104
|
+
'保持核心人格,不因剧情状态改写核心设定。只承接有记录的事件;不确定的往事先检索,不编造共同经历。',
|
|
105
|
+
].filter(Boolean).join('\n');
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=domain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.js","sourceRoot":"","sources":["../../src/character/domain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Companion, PartnerState } from '../domain.js';
|
|
2
|
+
import type { SessionEvent } from '@deepseek-ai/dsh-session';
|
|
3
|
+
export interface IdleContactPolicy {
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
routeId: string;
|
|
6
|
+
idleMinutes: number;
|
|
7
|
+
dailyLimit: number;
|
|
8
|
+
quietStartHour: number;
|
|
9
|
+
quietEndHour: number;
|
|
10
|
+
}
|
|
11
|
+
export interface IdleContactState {
|
|
12
|
+
timeZone: string;
|
|
13
|
+
policyRevision: number;
|
|
14
|
+
userMessageId: string;
|
|
15
|
+
messageId: string;
|
|
16
|
+
attemptedAt: number;
|
|
17
|
+
day: string;
|
|
18
|
+
count: number;
|
|
19
|
+
}
|
|
20
|
+
export declare const DEFAULT_IDLE_CONTACT: IdleContactPolicy;
|
|
21
|
+
export declare const IDLE_CONTACT_NOTICE = "\u4F19\u4F34\u95F2\u65F6\u4E3B\u52A8\u8054\u7CFB";
|
|
22
|
+
export declare function normalizeIdleContact(value: unknown): IdleContactPolicy;
|
|
23
|
+
export declare function idleContactDay(now: number, timeZone: string): string;
|
|
24
|
+
export declare function idleContactQuiet(policy: IdleContactPolicy, now: number, timeZone: string): boolean;
|
|
25
|
+
export declare function idleContactRouteAllowed(state: PartnerState, companion: Companion, routeId: string): boolean;
|
|
26
|
+
export declare function lastIdleContactUser(events: readonly SessionEvent[]): {
|
|
27
|
+
id: string;
|
|
28
|
+
at: number;
|
|
29
|
+
} | undefined;
|
|
30
|
+
export declare function idleContactDue(state: PartnerState, companion: Companion, user: {
|
|
31
|
+
id: string;
|
|
32
|
+
at: number;
|
|
33
|
+
} | undefined, now: number, timeZone: string): boolean;
|
|
34
|
+
export declare function isIdleContactNotice(event: SessionEvent): boolean;
|
|
35
|
+
//# sourceMappingURL=idle-contact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idle-contact.d.ts","sourceRoot":"","sources":["../../src/character/idle-contact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAE5D,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;CACrB;AACD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CACd;AACD,eAAO,MAAM,oBAAoB,EAAE,iBAAyH,CAAA;AAC5J,eAAO,MAAM,mBAAmB,qDAAa,CAAA;AAC7C,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,CActE;AACD,wBAAgB,cAAc,CAAC,GAAG,EAAC,MAAM,EAAC,QAAQ,EAAC,MAAM,GAAE,MAAM,CAEhE;AACD,wBAAgB,gBAAgB,CAAC,MAAM,EAAC,iBAAiB,EAAC,GAAG,EAAC,MAAM,EAAC,QAAQ,EAAC,MAAM,GAAE,OAAO,CAI5F;AACD,wBAAgB,uBAAuB,CAAC,KAAK,EAAC,YAAY,EAAC,SAAS,EAAC,SAAS,EAAC,OAAO,EAAC,MAAM,GAAE,OAAO,CAGrG;AACD,wBAAgB,mBAAmB,CAAC,MAAM,EAAC,SAAS,YAAY,EAAE,GAAE;IAAC,EAAE,EAAC,MAAM,CAAC;IAAA,EAAE,EAAC,MAAM,CAAA;CAAC,GAAC,SAAS,CAMlG;AACD,wBAAgB,cAAc,CAAC,KAAK,EAAC,YAAY,EAAC,SAAS,EAAC,SAAS,EAAC,IAAI,EAAC;IAAC,EAAE,EAAC,MAAM,CAAC;IAAA,EAAE,EAAC,MAAM,CAAA;CAAC,GAAC,SAAS,EAAC,GAAG,EAAC,MAAM,EAAC,QAAQ,EAAC,MAAM,GAAE,OAAO,CAW7I;AACD,wBAAgB,mBAAmB,CAAC,KAAK,EAAC,YAAY,GAAE,OAAO,CAE9D"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export const DEFAULT_IDLE_CONTACT = { enabled: false, routeId: '', idleMinutes: 120, dailyLimit: 2, quietStartHour: 23, quietEndHour: 9 };
|
|
2
|
+
export const IDLE_CONTACT_NOTICE = '伙伴闲时主动联系';
|
|
3
|
+
export function normalizeIdleContact(value) {
|
|
4
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
5
|
+
throw new Error('闲时联系配置无效');
|
|
6
|
+
const v = value;
|
|
7
|
+
if (typeof v.enabled !== 'boolean')
|
|
8
|
+
throw new Error('请选择是否开启闲时联系');
|
|
9
|
+
const result = { ...DEFAULT_IDLE_CONTACT, enabled: v.enabled };
|
|
10
|
+
if (typeof v.routeId !== 'string' || v.routeId.length > 200)
|
|
11
|
+
throw new Error('请选择联系会话');
|
|
12
|
+
result.routeId = v.routeId;
|
|
13
|
+
for (const [key, min, max] of [['idleMinutes', 30, 1440], ['dailyLimit', 1, 5], ['quietStartHour', 0, 23], ['quietEndHour', 0, 23]]) {
|
|
14
|
+
const number = v[key] ?? result[key];
|
|
15
|
+
if (typeof number !== 'number' || !Number.isInteger(number) || number < min || number > max)
|
|
16
|
+
throw new Error(`${key} 须为 ${min}–${max} 的整数`);
|
|
17
|
+
result[key] = number;
|
|
18
|
+
}
|
|
19
|
+
if (result.enabled && !result.routeId)
|
|
20
|
+
throw new Error('请先选择联系会话');
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
export function idleContactDay(now, timeZone) {
|
|
24
|
+
return new Intl.DateTimeFormat('en-CA', { timeZone, year: 'numeric', month: '2-digit', day: '2-digit' }).format(now);
|
|
25
|
+
}
|
|
26
|
+
export function idleContactQuiet(policy, now, timeZone) {
|
|
27
|
+
const hour = Number(new Intl.DateTimeFormat('en-GB', { timeZone, hour: '2-digit', hourCycle: 'h23' }).format(now));
|
|
28
|
+
const { quietStartHour: start, quietEndHour: end } = policy;
|
|
29
|
+
return start === end ? false : start < end ? hour >= start && hour < end : hour >= start || hour < end;
|
|
30
|
+
}
|
|
31
|
+
export function idleContactRouteAllowed(state, companion, routeId) {
|
|
32
|
+
const route = state.sessions.find(r => r.id === routeId && r.companionId === companion.id);
|
|
33
|
+
return Boolean(route && (route.kind === 'local' || (state.channels.some(c => c.id === route.channelId && c.companionId === companion.id && c.enabled) && state.pairings.some(p => p.channelId === route.channelId && p.userId === route.userId && p.status === 'approved'))));
|
|
34
|
+
}
|
|
35
|
+
export function lastIdleContactUser(events) {
|
|
36
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
37
|
+
const e = events[i];
|
|
38
|
+
if (e.type === 'user/message' && e.data.source.kind === 'user')
|
|
39
|
+
return { id: e.data.id, at: e.time };
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
export function idleContactDue(state, companion, user, now, timeZone) {
|
|
44
|
+
const policy = companion.idleContact;
|
|
45
|
+
if (!policy?.enabled || !user || !idleContactRouteAllowed(state, companion, policy.routeId) || idleContactQuiet(policy, now, timeZone))
|
|
46
|
+
return false;
|
|
47
|
+
const route = state.sessions.find(r => r.id === policy.routeId);
|
|
48
|
+
const previous = route.idleContactState;
|
|
49
|
+
if (previous?.userMessageId === user.id)
|
|
50
|
+
return false; // Never nag again until a real new user message.
|
|
51
|
+
const latestActivity = Math.max(user.at, ...state.sessions.filter(r => r.companionId === companion.id).map(r => r.lastMessageAt), previous?.attemptedAt ?? 0);
|
|
52
|
+
if (now - latestActivity < policy.idleMinutes * 60_000)
|
|
53
|
+
return false;
|
|
54
|
+
const day = idleContactDay(now, timeZone);
|
|
55
|
+
const attempts = state.sessions.filter(r => r.companionId === companion.id).reduce((n, r) => n + (r.idleContactState?.day === day ? r.idleContactState.count : 0), 0);
|
|
56
|
+
return attempts < policy.dailyLimit;
|
|
57
|
+
}
|
|
58
|
+
export function isIdleContactNotice(event) {
|
|
59
|
+
return event.type === 'user/message' && event.data.source.kind === 'plugin:@lemoncat7/dsh-partner' && event.data.source.form === 'notice' && event.data.source.summary === IDLE_CONTACT_NOTICE;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=idle-contact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idle-contact.js","sourceRoot":"","sources":["../../src/character/idle-contact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { Companion } from '../domain.js';
|
|
3
|
+
/** Isolated trial: no tools, session persistence, memory extraction or channel delivery. */
|
|
4
|
+
export declare function previewCharacter(ctx: Context, companion: Companion, body: Record<string, unknown>): Promise<{
|
|
5
|
+
model: string;
|
|
6
|
+
provider: string;
|
|
7
|
+
reasoningEffort?: import("@deepseek-ai/dsh-llm").ReasoningEffortId;
|
|
8
|
+
reply: string;
|
|
9
|
+
firstTokenMs: number | undefined;
|
|
10
|
+
durationMs: number;
|
|
11
|
+
}>;
|
|
12
|
+
//# sourceMappingURL=preview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/character/preview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAI7C,4FAA4F;AAC5F,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;GAsCvG"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { createAssistantMessage, createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
2
|
+
import { normalizeCharacterCard, renderCharacterContext } from './domain.js';
|
|
3
|
+
import { renderPartnerPersona } from '../execution/agent-support.js';
|
|
4
|
+
const running = new Set();
|
|
5
|
+
/** Isolated trial: no tools, session persistence, memory extraction or channel delivery. */
|
|
6
|
+
export async function previewCharacter(ctx, companion, body) {
|
|
7
|
+
if (running.has(companion.id))
|
|
8
|
+
throw new Error('该伙伴的试聊正在生成,请稍候');
|
|
9
|
+
const card = normalizeCharacterCard(body.card);
|
|
10
|
+
if (!card.enabled)
|
|
11
|
+
throw new Error('请先开启人格强化再试聊');
|
|
12
|
+
if (typeof body.message !== 'string' || !body.message.trim() || body.message.length > 2000)
|
|
13
|
+
throw new Error('试聊消息须为 1–2000 字');
|
|
14
|
+
const history = Array.isArray(body.history) ? body.history.slice(-8).map(entry => {
|
|
15
|
+
if (!entry || typeof entry !== 'object')
|
|
16
|
+
throw new Error('试聊历史格式无效');
|
|
17
|
+
const e = entry;
|
|
18
|
+
return { user: String(e.user ?? '').slice(0, 2000), assistant: String(e.assistant ?? '').slice(0, 3000) };
|
|
19
|
+
}) : [];
|
|
20
|
+
const defaults = ctx.get('agentDefaultModel');
|
|
21
|
+
if (!defaults)
|
|
22
|
+
throw new Error('默认模型服务不可用');
|
|
23
|
+
const selection = { ...defaults.currentSelection(), ...(companion.provider ? { provider: companion.provider } : {}), ...(companion.model ? { model: companion.model } : {}) };
|
|
24
|
+
// Replay ordinary dialogue roles, as in a real conversation. A JSON transcript
|
|
25
|
+
// inside one user message encourages commentary about the character instead.
|
|
26
|
+
const messages = [];
|
|
27
|
+
for (const entry of history) {
|
|
28
|
+
if (entry.user.trim())
|
|
29
|
+
messages.push(createUserMessage({ content: [{ type: 'text', text: entry.user }], source: { kind: 'user' } }));
|
|
30
|
+
if (entry.assistant.trim())
|
|
31
|
+
messages.push(createAssistantMessage({ content: [{ type: 'text', text: entry.assistant }], source: selection }));
|
|
32
|
+
}
|
|
33
|
+
messages.push(createUserMessage({ content: [{ type: 'text', text: body.message }], source: { kind: 'user' } }));
|
|
34
|
+
running.add(companion.id);
|
|
35
|
+
const controller = new AbortController();
|
|
36
|
+
const timeout = setTimeout(() => controller.abort(), 90_000);
|
|
37
|
+
let reply = '';
|
|
38
|
+
let firstTokenMs;
|
|
39
|
+
let completed = false;
|
|
40
|
+
const started = Date.now();
|
|
41
|
+
try {
|
|
42
|
+
for await (const chunk of ctx.llm.stream({ ...selection,
|
|
43
|
+
system: `${renderPartnerPersona({ ...companion, characterCard: card }, 'local')}\n${renderCharacterContext(card, history.map(e => e.user + e.assistant).join('\n') + body.message)}\n这是独立试聊:只依据提供的对话回应,没有工具,不执行真实操作,不读取或写入正式记忆,不向任何渠道发送消息;身份里列出的工作能力在本次试聊不可用。`,
|
|
44
|
+
messages,
|
|
45
|
+
maxTokens: 1200, signal: controller.signal,
|
|
46
|
+
})) {
|
|
47
|
+
if (chunk.type === 'text-delta') {
|
|
48
|
+
firstTokenMs ??= Date.now() - started;
|
|
49
|
+
reply += chunk.text;
|
|
50
|
+
}
|
|
51
|
+
if (chunk.type === 'finish') {
|
|
52
|
+
if (chunk.reason.kind !== 'stop')
|
|
53
|
+
throw new Error(`试聊未完成:${chunk.reason.kind}`);
|
|
54
|
+
completed = true;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!completed || !reply.trim())
|
|
58
|
+
throw new Error('试聊流未完整结束,请重试');
|
|
59
|
+
return { reply, firstTokenMs, durationMs: Date.now() - started, ...selection };
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
clearTimeout(timeout);
|
|
63
|
+
running.delete(companion.id);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=preview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/character/preview.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
import { type CharacterState } from './domain.js';
|
|
3
|
+
export declare function initializeCharacterState(db: DatabaseSync): void;
|
|
4
|
+
export declare function readCharacterState(db: DatabaseSync, scope: string): CharacterState;
|
|
5
|
+
export declare function saveCharacterState(db: DatabaseSync, scope: string, value: unknown, expectedAt: number): CharacterState;
|
|
6
|
+
/** Automatic updates cannot overwrite user pins or newer manual edits. */
|
|
7
|
+
export declare function applyCharacterState(db: DatabaseSync, scope: string, value: unknown, at: number, sourceTurnId: string): void;
|
|
8
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/character/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAgD,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AAC/F,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAG/D;AACD,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAGlF;AACD,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,CAMtH;AACD,0EAA0E;AAC1E,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAM3H"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { emptyCharacterState, normalizeCharacterState } from './domain.js';
|
|
2
|
+
export function initializeCharacterState(db) {
|
|
3
|
+
db.exec(`CREATE TABLE IF NOT EXISTS character_states(scope_id TEXT PRIMARY KEY, state_json TEXT NOT NULL);
|
|
4
|
+
CREATE TABLE IF NOT EXISTS context_renewals(session_id TEXT PRIMARY KEY, day TEXT NOT NULL, at INTEGER NOT NULL, removed INTEGER NOT NULL);`);
|
|
5
|
+
}
|
|
6
|
+
export function readCharacterState(db, scope) {
|
|
7
|
+
const row = db.prepare('SELECT state_json FROM character_states WHERE scope_id=?').get(scope);
|
|
8
|
+
return row ? JSON.parse(String(row.state_json)) : emptyCharacterState();
|
|
9
|
+
}
|
|
10
|
+
export function saveCharacterState(db, scope, value, expectedAt) {
|
|
11
|
+
const previous = readCharacterState(db, scope);
|
|
12
|
+
if (previous.updatedAt !== expectedAt)
|
|
13
|
+
throw new Error('角色记忆已更新,请刷新后再保存');
|
|
14
|
+
const state = { ...normalizeCharacterState(value), updatedAt: Math.max(Date.now(), previous.updatedAt + 1) };
|
|
15
|
+
db.prepare('INSERT INTO character_states VALUES (?,?) ON CONFLICT(scope_id) DO UPDATE SET state_json=excluded.state_json').run(scope, JSON.stringify(state));
|
|
16
|
+
return state;
|
|
17
|
+
}
|
|
18
|
+
/** Automatic updates cannot overwrite user pins or newer manual edits. */
|
|
19
|
+
export function applyCharacterState(db, scope, value, at, sourceTurnId) {
|
|
20
|
+
const previous = readCharacterState(db, scope);
|
|
21
|
+
if (previous.updatedAt > at || previous.sourceTurnId === sourceTurnId)
|
|
22
|
+
return;
|
|
23
|
+
const next = normalizeCharacterState(value);
|
|
24
|
+
const state = { ...next, pins: previous.pins, updatedAt: at, sourceTurnId };
|
|
25
|
+
db.prepare('INSERT INTO character_states VALUES (?,?) ON CONFLICT(scope_id) DO UPDATE SET state_json=excluded.state_json').run(scope, JSON.stringify(state));
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/character/store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAuB,MAAM,aAAa,CAAA;AAC/F,MAAM,UAAU,wBAAwB,CAAC,EAAgB;IACvD,EAAE,CAAC,IAAI,CAAC;gJACsI,CAAC,CAAA;AACjJ,CAAC;AACD,MAAM,UAAU,kBAAkB,CAAC,EAAgB,EAAE,KAAa;IAChE,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,0DAA0D,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IAC7F,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAmB,CAAC,CAAC,CAAC,mBAAmB,EAAE,CAAA;AAC3F,CAAC;AACD,MAAM,UAAU,kBAAkB,CAAC,EAAgB,EAAE,KAAa,EAAE,KAAc,EAAE,UAAkB;IACpG,MAAM,QAAQ,GAAG,kBAAkB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;IAC9C,IAAI,QAAQ,CAAC,SAAS,KAAK,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACzE,MAAM,KAAK,GAAG,EAAE,GAAG,uBAAuB,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,CAAA;IAC5G,EAAE,CAAC,OAAO,CAAC,8GAA8G,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;IAC5J,OAAO,KAAK,CAAA;AACd,CAAC;AACD,0EAA0E;AAC1E,MAAM,UAAU,mBAAmB,CAAC,EAAgB,EAAE,KAAa,EAAE,KAAc,EAAE,EAAU,EAAE,YAAoB;IACnH,MAAM,QAAQ,GAAG,kBAAkB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;IAC9C,IAAI,QAAQ,CAAC,SAAS,GAAG,EAAE,IAAI,QAAQ,CAAC,YAAY,KAAK,YAAY;QAAE,OAAM;IAC7E,MAAM,IAAI,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAA;IAC3C,MAAM,KAAK,GAAmB,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,YAAY,EAAE,CAAA;IAC3F,EAAE,CAAC,OAAO,CAAC,8GAA8G,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;AAC9J,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { ConversationNodeDefinition } from '@deepseek-ai/dsh-client-ui-conversation/client';
|
|
3
|
+
import { type ChatReply } from './protocol.js';
|
|
4
|
+
/** Project durable delivery metadata into the host's normal assistant renderer.
|
|
5
|
+
* This is a view only: no synthetic assistant messages or history rewrites.
|
|
6
|
+
*/
|
|
7
|
+
export declare function nativeChatBlocks(reply: ChatReply, base?: string | undefined): Array<{
|
|
8
|
+
kind: 'text';
|
|
9
|
+
text: string;
|
|
10
|
+
}>;
|
|
11
|
+
export declare const chatReplyDefinition: ConversationNodeDefinition<ChatReply>;
|
|
12
|
+
export declare function registerChatReplies(ctx: Context): void;
|
|
13
|
+
//# sourceMappingURL=conversation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/chat/conversation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAA;AAChG,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,eAAe,CAAA;AAElE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,qBAAiE,GAAG,KAAK,CAAC;IAAC,IAAI,EAAC,MAAM,CAAC;IAAA,IAAI,EAAC,MAAM,CAAA;CAAC,CAAC,CAG1J;AACD,eAAO,MAAM,mBAAmB,EAAC,0BAA0B,CAAC,SAAS,CAYpE,CAAA;AACD,wBAAgB,mBAAmB,CAAC,GAAG,EAAC,OAAO,GAAE,IAAI,CAWpD"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { chatReplyFromEvent } from './protocol.js';
|
|
2
|
+
/** Project durable delivery metadata into the host's normal assistant renderer.
|
|
3
|
+
* This is a view only: no synthetic assistant messages or history rewrites.
|
|
4
|
+
*/
|
|
5
|
+
export function nativeChatBlocks(reply, base = typeof document === 'undefined' ? undefined : document.baseURI) {
|
|
6
|
+
return reply.parts.map(part => ({ kind: 'text', text: part.type === 'text' ? part.text
|
|
7
|
+
: `![${part.label.replace(/[\\\[\]]/g, '\\$&')}](${encodeURI(base ? new URL(part.url, base).href : part.url).replace(/[()]/g, c => `%${c.charCodeAt(0).toString(16)}`)})` }));
|
|
8
|
+
}
|
|
9
|
+
export const chatReplyDefinition = {
|
|
10
|
+
kind: 'partner-chat-reply', target: 'chat',
|
|
11
|
+
match: event => chatReplyFromEvent(event) ? { id: `reply-${event.seq}`, role: 'start' } : null,
|
|
12
|
+
start: (_ctx, match) => chatReplyFromEvent(match.event),
|
|
13
|
+
update: (_ctx, match) => chatReplyFromEvent(match.event),
|
|
14
|
+
buildViewNode: context => {
|
|
15
|
+
if (!context.state || !context.start)
|
|
16
|
+
return null;
|
|
17
|
+
const { event, location } = context.start;
|
|
18
|
+
return { key: context.key, id: context.id, kind: 'assistant-step', target: 'chat', anchorSeq: event.seq, location,
|
|
19
|
+
visibility: 'visible', groupTree: 'turn', data: { status: 'settled', turn: 'turn' in event.data ? event.data.turn : 0,
|
|
20
|
+
step: 'step' in event.data ? event.data.step : 0, time: event.time, blocks: nativeChatBlocks(context.state) } };
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
export function registerChatReplies(ctx) {
|
|
24
|
+
const runtime = ctx;
|
|
25
|
+
const registered = new WeakSet();
|
|
26
|
+
const register = (scope, modern) => {
|
|
27
|
+
const registry = modern ? scope.get('conversationEvents') : scope.get('uiConversation').events;
|
|
28
|
+
if (registered.has(registry))
|
|
29
|
+
return;
|
|
30
|
+
registered.add(registry);
|
|
31
|
+
scope.effect(() => { const dispose = registry.register(chatReplyDefinition); return () => { registered.delete(registry); dispose(); }; }, 'partner: chat replies');
|
|
32
|
+
};
|
|
33
|
+
runtime.inject(['uiConversation'], scope => register(scope, false));
|
|
34
|
+
runtime.inject(['conversationEvents'], scope => register(scope, true));
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=conversation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.js","sourceRoot":"","sources":["../../src/chat/conversation.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAkB,MAAM,eAAe,CAAA;AAElE;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAgB,EAAE,IAAI,GAAG,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO;IACtH,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAC,IAAI,EAAC,MAAM,EAAE,IAAI,EAAC,IAAI,CAAC,IAAI,KAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI;YAC/E,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAC,MAAM,CAAC,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAC,CAAC,CAAA,EAAE,CAAA,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAC,CAAC,CAAC,CAAA;AAC5K,CAAC;AACD,MAAM,CAAC,MAAM,mBAAmB,GAAuC;IACrE,IAAI,EAAC,oBAAoB,EAAC,MAAM,EAAC,MAAM;IACvC,KAAK,EAAC,KAAK,CAAA,EAAE,CAAA,kBAAkB,CAAC,KAAqB,CAAC,CAAA,CAAC,CAAA,EAAC,EAAE,EAAC,SAAS,KAAK,CAAC,GAAG,EAAE,EAAC,IAAI,EAAC,OAAO,EAAC,CAAA,CAAC,CAAA,IAAI;IAClG,KAAK,EAAC,CAAC,IAAI,EAAC,KAAK,EAAC,EAAE,CAAA,kBAAkB,CAAC,KAAK,CAAC,KAAqB,CAAE;IACpE,MAAM,EAAC,CAAC,IAAI,EAAC,KAAK,EAAC,EAAE,CAAA,kBAAkB,CAAC,KAAK,CAAC,KAAqB,CAAE;IACrE,aAAa,EAAC,OAAO,CAAA,EAAE;QACrB,IAAI,CAAC,OAAO,CAAC,KAAK,IAAE,CAAC,OAAO,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QAC/C,MAAM,EAAC,KAAK,EAAC,QAAQ,EAAC,GAAC,OAAO,CAAC,KAAK,CAAA;QACpC,OAAO,EAAC,GAAG,EAAC,OAAO,CAAC,GAAG,EAAC,EAAE,EAAC,OAAO,CAAC,EAAE,EAAC,IAAI,EAAC,gBAAgB,EAAC,MAAM,EAAC,MAAM,EAAC,SAAS,EAAC,KAAK,CAAC,GAAG,EAAC,QAAQ;YACpG,UAAU,EAAC,SAAS,EAAC,SAAS,EAAC,MAAM,EAAC,IAAI,EAAC,EAAC,MAAM,EAAC,SAAS,EAAC,IAAI,EAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAA,CAAC,CAAA,KAAK,CAAC,IAAI,CAAC,IAAI,CAAA,CAAC,CAAA,CAAC;gBACtG,IAAI,EAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAA,CAAC,CAAA,KAAK,CAAC,IAAI,CAAC,IAAI,CAAA,CAAC,CAAA,CAAC,EAAC,IAAI,EAAC,KAAK,CAAC,IAAI,EAAC,MAAM,EAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAC,EAAC,CAAA;IAC1G,CAAC;CACF,CAAA;AACD,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,MAAM,OAAO,GAAC,GAAiF,CAAA;IAC/F,MAAM,UAAU,GAAC,IAAI,OAAO,EAAU,CAAA;IACtC,MAAM,QAAQ,GAAC,CAAC,KAAa,EAAC,MAAc,EAAC,EAAE;QAE7C,MAAM,QAAQ,GAAC,MAAM,CAAA,CAAC,CAAA,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAa,CAAA,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAuB,CAAC,MAAM,CAAA;QAC3H,IAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAC,OAAM;QAClC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACxB,KAAK,CAAC,MAAM,CAAC,GAAE,EAAE,GAAC,MAAM,OAAO,GAAC,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAA,OAAM,GAAE,EAAE,GAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAA,OAAO,EAAE,CAAA,CAAA,CAAC,CAAA,CAAA,CAAC,EAAC,uBAAuB,CAAC,CAAA;IACpJ,CAAC,CAAA;IACD,OAAO,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,EAAC,KAAK,CAAA,EAAE,CAAA,QAAQ,CAAC,KAAK,EAAC,KAAK,CAAC,CAAC,CAAC;IAAA,OAAO,CAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,EAAC,KAAK,CAAA,EAAE,CAAA,QAAQ,CAAC,KAAK,EAAC,IAAI,CAAC,CAAC,CAAA;AACpI,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { SessionEvent } from '@deepseek-ai/dsh-session';
|
|
2
|
+
import type { PartnerOutboundAttachment, PartnerReply } from '../channel-message.js';
|
|
3
|
+
export type ChatPart = {
|
|
4
|
+
type: 'text';
|
|
5
|
+
text: string;
|
|
6
|
+
} | {
|
|
7
|
+
type: 'image';
|
|
8
|
+
attachment: PartnerOutboundAttachment;
|
|
9
|
+
url: string;
|
|
10
|
+
label: string;
|
|
11
|
+
};
|
|
12
|
+
export interface ChatReply {
|
|
13
|
+
kind: 'partner-chat-v1';
|
|
14
|
+
parts: ChatPart[];
|
|
15
|
+
originRouteId?: string | null;
|
|
16
|
+
}
|
|
17
|
+
export declare function chatReplyFromEvent(event: SessionEvent): ChatReply | undefined;
|
|
18
|
+
/** Legacy records keep text at 0 and attachments at 1+. New replies preserve authored order. */
|
|
19
|
+
export declare function replyDeliveryParts(reply: PartnerReply): Array<{
|
|
20
|
+
type: 'text';
|
|
21
|
+
text: string;
|
|
22
|
+
} | {
|
|
23
|
+
type: 'image';
|
|
24
|
+
attachment: PartnerOutboundAttachment;
|
|
25
|
+
}>;
|
|
26
|
+
export declare function parseChatInput(raw: unknown): Array<{
|
|
27
|
+
text: string;
|
|
28
|
+
} | {
|
|
29
|
+
stickerId: string;
|
|
30
|
+
}>;
|
|
31
|
+
/** Some providers put speech beside a terminal tool call instead of inside its arguments.
|
|
32
|
+
* Preserve only that exact call's public text, never reasoning, earlier steps or other tools.
|
|
33
|
+
*/
|
|
34
|
+
export declare function withChatCompanionText(input: Array<{
|
|
35
|
+
text: string;
|
|
36
|
+
} | {
|
|
37
|
+
stickerId: string;
|
|
38
|
+
}>, events: readonly SessionEvent[], callId: string | undefined): Array<{
|
|
39
|
+
text: string;
|
|
40
|
+
} | {
|
|
41
|
+
stickerId: string;
|
|
42
|
+
}>;
|
|
43
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/chat/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEpF,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,yBAAyB,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAC5I,MAAM,WAAW,SAAS;IAAG,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE;AACxG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,SAAS,GAAG,SAAS,CAO7E;AACD,gGAAgG;AAChG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,KAAK,CAAC;IAAC,IAAI,EAAC,MAAM,CAAC;IAAA,IAAI,EAAC,MAAM,CAAA;CAAC,GAAG;IAAC,IAAI,EAAC,OAAO,CAAC;IAAA,UAAU,EAAC,yBAAyB,CAAA;CAAC,CAAC,CAG9I;AACD,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAAC;IAAC,IAAI,EAAC,MAAM,CAAA;CAAC,GAAG;IAAC,SAAS,EAAC,MAAM,CAAA;CAAC,CAAC,CActF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,IAAI,EAAC,MAAM,CAAA;CAAC,GAAG;IAAC,SAAS,EAAC,MAAM,CAAA;CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC;IAAC,IAAI,EAAC,MAAM,CAAA;CAAC,GAAG;IAAC,SAAS,EAAC,MAAM,CAAA;CAAC,CAAC,CAiB9L"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export function chatReplyFromEvent(event) {
|
|
2
|
+
if (event.type !== 'tool/result' && event.type !== 'tool/ptc-dispatch')
|
|
3
|
+
return;
|
|
4
|
+
if (!event.data || (event.type === 'tool/result' ? event.data.message?.isError : event.data.isError))
|
|
5
|
+
return;
|
|
6
|
+
const value = event.data.meta;
|
|
7
|
+
if (value?.kind !== 'partner-chat-v1' || !Array.isArray(value.parts) || !value.parts.length || value.parts.length > 8)
|
|
8
|
+
return;
|
|
9
|
+
if (!value.parts.every(p => p && typeof p === 'object' && (p.type === 'text' ? typeof p.text === 'string' && !!p.text.trim() : p.type === 'image' && p.attachment?.kind === 'image' && typeof p.url === 'string' && p.url.startsWith('/') && !p.url.startsWith('//') && typeof p.label === 'string')))
|
|
10
|
+
return;
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
/** Legacy records keep text at 0 and attachments at 1+. New replies preserve authored order. */
|
|
14
|
+
export function replyDeliveryParts(reply) {
|
|
15
|
+
if (reply.chatParts?.length)
|
|
16
|
+
return reply.chatParts.map(p => reply.attachmentPolicy === 'text-only' && p.type === 'image' ? { type: 'text', text: '' } : p);
|
|
17
|
+
return [{ type: 'text', text: reply.text }, ...(reply.attachmentPolicy === 'text-only' ? [] : reply.attachments.map(attachment => ({ type: 'image', attachment })))];
|
|
18
|
+
}
|
|
19
|
+
export function parseChatInput(raw) {
|
|
20
|
+
const input = raw;
|
|
21
|
+
if (!input || !Array.isArray(input.messages) || !input.messages.length || input.messages.length > 8)
|
|
22
|
+
throw new Error('请提交 1–8 条消息,普通文字不需要拆句');
|
|
23
|
+
let total = 0, images = 0;
|
|
24
|
+
const parts = input.messages.map(value => {
|
|
25
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
26
|
+
throw new Error('每条消息只能是文字或一个表情 ID');
|
|
27
|
+
const v = value;
|
|
28
|
+
if (Object.keys(v).length !== 1)
|
|
29
|
+
throw new Error('文字和表情要分成两条消息');
|
|
30
|
+
if (typeof v.text === 'string' && v.text.trim() && v.text.length <= 6000) {
|
|
31
|
+
total += v.text.length;
|
|
32
|
+
return { text: v.text.trim() };
|
|
33
|
+
}
|
|
34
|
+
if (typeof v.stickerId === 'string' && /^[a-zA-Z0-9_-]{1,80}$/.test(v.stickerId)) {
|
|
35
|
+
images++;
|
|
36
|
+
return { stickerId: v.stickerId };
|
|
37
|
+
}
|
|
38
|
+
throw new Error('文字不能为空或超过 6000 字;表情必须使用库内 ID');
|
|
39
|
+
});
|
|
40
|
+
if (total > 12000 || images > 2)
|
|
41
|
+
throw new Error('一轮最多 12000 字、2 张表情;不需要每轮发表情');
|
|
42
|
+
return parts;
|
|
43
|
+
}
|
|
44
|
+
/** Some providers put speech beside a terminal tool call instead of inside its arguments.
|
|
45
|
+
* Preserve only that exact call's public text, never reasoning, earlier steps or other tools.
|
|
46
|
+
*/
|
|
47
|
+
export function withChatCompanionText(input, events, callId) {
|
|
48
|
+
// Authored text inside messages is authoritative; surrounding prose can be a paraphrase or preamble.
|
|
49
|
+
if (!callId || input.some(part => 'text' in part))
|
|
50
|
+
return input;
|
|
51
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
52
|
+
const event = events[i];
|
|
53
|
+
if (event.type === 'turn/start' || event.type === 'user/message')
|
|
54
|
+
break;
|
|
55
|
+
if (event.type !== 'assistant/message')
|
|
56
|
+
continue;
|
|
57
|
+
const blocks = event.data.message.content;
|
|
58
|
+
const calls = blocks.filter(b => b.type === 'tool-call');
|
|
59
|
+
if (!calls.some(c => c.id === callId))
|
|
60
|
+
continue;
|
|
61
|
+
if (event.data.interrupted || calls.length !== 1 || calls[0].name !== 'partner_chat_reply')
|
|
62
|
+
return input;
|
|
63
|
+
const speech = blocks.filter(b => b.type === 'text').map(b => b.text.trim()).filter(Boolean).join('\n');
|
|
64
|
+
if (!speech)
|
|
65
|
+
return input;
|
|
66
|
+
// The protocol's size limits remain authoritative; a rejected oversized call can be corrected.
|
|
67
|
+
return parseChatInput({ messages: [{ text: speech }, ...input] });
|
|
68
|
+
}
|
|
69
|
+
return input;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=protocol.js.map
|