@xinghunm/ai-chat 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +43 -5
- package/dist/index.d.ts +43 -5
- package/dist/index.js +36 -3
- package/dist/index.mjs +36 -3
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -102,11 +102,28 @@ interface PlanBooleanQuestion extends PlanQuestionBase {
|
|
|
102
102
|
*/
|
|
103
103
|
type PlanQuestion = PlanSingleSelectQuestion | PlanMultiSelectQuestion | PlanTextQuestion | PlanNumberQuestion | PlanBooleanQuestion;
|
|
104
104
|
type PlanQuestionnaireStatus = 'expired' | 'failed';
|
|
105
|
+
/**
|
|
106
|
+
* Merge behavior applied when a keyed structured block is patched repeatedly.
|
|
107
|
+
*/
|
|
108
|
+
type ChatBlockMergePolicy = 'append' | 'replace' | 'ignore-duplicate';
|
|
105
109
|
/**
|
|
106
110
|
* Structured question form emitted for plan-mode clarification flows.
|
|
107
111
|
*/
|
|
108
112
|
interface PlanQuestionnaire {
|
|
109
113
|
questionnaireId: string;
|
|
114
|
+
/**
|
|
115
|
+
* Stable key used to identify the same logical questionnaire across streaming patches.
|
|
116
|
+
* When present, questionnaires are merged by `blockKey` instead of `questionnaireId`.
|
|
117
|
+
*/
|
|
118
|
+
blockKey?: string;
|
|
119
|
+
/**
|
|
120
|
+
* Merge strategy used when another questionnaire with the same key arrives.
|
|
121
|
+
*
|
|
122
|
+
* - `append`: keep appending questionnaires even if the key matches.
|
|
123
|
+
* - `replace`: replace the existing keyed questionnaire with the latest one.
|
|
124
|
+
* - `ignore-duplicate`: keep the first keyed questionnaire and ignore later duplicates.
|
|
125
|
+
*/
|
|
126
|
+
mergePolicy?: ChatBlockMergePolicy;
|
|
110
127
|
title?: string;
|
|
111
128
|
description?: string;
|
|
112
129
|
submitLabel?: string;
|
|
@@ -120,6 +137,10 @@ interface PlanQuestionnaire {
|
|
|
120
137
|
*/
|
|
121
138
|
interface PlanQuestionnaireSubmission {
|
|
122
139
|
questionnaireId: string;
|
|
140
|
+
/**
|
|
141
|
+
* Stable questionnaire block key forwarded from the rendered card when available.
|
|
142
|
+
*/
|
|
143
|
+
blockKey?: string;
|
|
123
144
|
answers: Record<string, PlanQuestionnaireAnswerValue>;
|
|
124
145
|
content: string;
|
|
125
146
|
sourceMessageId?: string;
|
|
@@ -168,6 +189,27 @@ interface ResultSummary {
|
|
|
168
189
|
headline: string;
|
|
169
190
|
details: string[];
|
|
170
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Extensible custom block rendered by a consumer-provided block renderer.
|
|
194
|
+
*/
|
|
195
|
+
interface ChatCustomBlock {
|
|
196
|
+
type: 'custom';
|
|
197
|
+
kind: string;
|
|
198
|
+
data: unknown;
|
|
199
|
+
/**
|
|
200
|
+
* Stable key used to identify the same logical block across streaming patches.
|
|
201
|
+
* When present, keyed custom blocks are merged by `blockKey` regardless of `kind`.
|
|
202
|
+
*/
|
|
203
|
+
blockKey?: string;
|
|
204
|
+
/**
|
|
205
|
+
* Merge strategy used when another custom block with the same key arrives.
|
|
206
|
+
*
|
|
207
|
+
* - `append`: keep appending blocks even if the key matches.
|
|
208
|
+
* - `replace`: replace the existing keyed block with the latest one.
|
|
209
|
+
* - `ignore-duplicate`: keep the first keyed block and ignore later duplicates.
|
|
210
|
+
*/
|
|
211
|
+
mergePolicy?: ChatBlockMergePolicy;
|
|
212
|
+
}
|
|
171
213
|
/**
|
|
172
214
|
* Structured assistant block variants rendered by the chat thread.
|
|
173
215
|
*/
|
|
@@ -190,11 +232,7 @@ type ChatMessageBlock = {
|
|
|
190
232
|
} | {
|
|
191
233
|
type: 'questionnaire';
|
|
192
234
|
questionnaire: PlanQuestionnaire;
|
|
193
|
-
} |
|
|
194
|
-
type: 'custom';
|
|
195
|
-
kind: string;
|
|
196
|
-
data: unknown;
|
|
197
|
-
};
|
|
235
|
+
} | ChatCustomBlock;
|
|
198
236
|
/**
|
|
199
237
|
* Supported message body render orders for mixed text and structured blocks.
|
|
200
238
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -102,11 +102,28 @@ interface PlanBooleanQuestion extends PlanQuestionBase {
|
|
|
102
102
|
*/
|
|
103
103
|
type PlanQuestion = PlanSingleSelectQuestion | PlanMultiSelectQuestion | PlanTextQuestion | PlanNumberQuestion | PlanBooleanQuestion;
|
|
104
104
|
type PlanQuestionnaireStatus = 'expired' | 'failed';
|
|
105
|
+
/**
|
|
106
|
+
* Merge behavior applied when a keyed structured block is patched repeatedly.
|
|
107
|
+
*/
|
|
108
|
+
type ChatBlockMergePolicy = 'append' | 'replace' | 'ignore-duplicate';
|
|
105
109
|
/**
|
|
106
110
|
* Structured question form emitted for plan-mode clarification flows.
|
|
107
111
|
*/
|
|
108
112
|
interface PlanQuestionnaire {
|
|
109
113
|
questionnaireId: string;
|
|
114
|
+
/**
|
|
115
|
+
* Stable key used to identify the same logical questionnaire across streaming patches.
|
|
116
|
+
* When present, questionnaires are merged by `blockKey` instead of `questionnaireId`.
|
|
117
|
+
*/
|
|
118
|
+
blockKey?: string;
|
|
119
|
+
/**
|
|
120
|
+
* Merge strategy used when another questionnaire with the same key arrives.
|
|
121
|
+
*
|
|
122
|
+
* - `append`: keep appending questionnaires even if the key matches.
|
|
123
|
+
* - `replace`: replace the existing keyed questionnaire with the latest one.
|
|
124
|
+
* - `ignore-duplicate`: keep the first keyed questionnaire and ignore later duplicates.
|
|
125
|
+
*/
|
|
126
|
+
mergePolicy?: ChatBlockMergePolicy;
|
|
110
127
|
title?: string;
|
|
111
128
|
description?: string;
|
|
112
129
|
submitLabel?: string;
|
|
@@ -120,6 +137,10 @@ interface PlanQuestionnaire {
|
|
|
120
137
|
*/
|
|
121
138
|
interface PlanQuestionnaireSubmission {
|
|
122
139
|
questionnaireId: string;
|
|
140
|
+
/**
|
|
141
|
+
* Stable questionnaire block key forwarded from the rendered card when available.
|
|
142
|
+
*/
|
|
143
|
+
blockKey?: string;
|
|
123
144
|
answers: Record<string, PlanQuestionnaireAnswerValue>;
|
|
124
145
|
content: string;
|
|
125
146
|
sourceMessageId?: string;
|
|
@@ -168,6 +189,27 @@ interface ResultSummary {
|
|
|
168
189
|
headline: string;
|
|
169
190
|
details: string[];
|
|
170
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Extensible custom block rendered by a consumer-provided block renderer.
|
|
194
|
+
*/
|
|
195
|
+
interface ChatCustomBlock {
|
|
196
|
+
type: 'custom';
|
|
197
|
+
kind: string;
|
|
198
|
+
data: unknown;
|
|
199
|
+
/**
|
|
200
|
+
* Stable key used to identify the same logical block across streaming patches.
|
|
201
|
+
* When present, keyed custom blocks are merged by `blockKey` regardless of `kind`.
|
|
202
|
+
*/
|
|
203
|
+
blockKey?: string;
|
|
204
|
+
/**
|
|
205
|
+
* Merge strategy used when another custom block with the same key arrives.
|
|
206
|
+
*
|
|
207
|
+
* - `append`: keep appending blocks even if the key matches.
|
|
208
|
+
* - `replace`: replace the existing keyed block with the latest one.
|
|
209
|
+
* - `ignore-duplicate`: keep the first keyed block and ignore later duplicates.
|
|
210
|
+
*/
|
|
211
|
+
mergePolicy?: ChatBlockMergePolicy;
|
|
212
|
+
}
|
|
171
213
|
/**
|
|
172
214
|
* Structured assistant block variants rendered by the chat thread.
|
|
173
215
|
*/
|
|
@@ -190,11 +232,7 @@ type ChatMessageBlock = {
|
|
|
190
232
|
} | {
|
|
191
233
|
type: 'questionnaire';
|
|
192
234
|
questionnaire: PlanQuestionnaire;
|
|
193
|
-
} |
|
|
194
|
-
type: 'custom';
|
|
195
|
-
kind: string;
|
|
196
|
-
data: unknown;
|
|
197
|
-
};
|
|
235
|
+
} | ChatCustomBlock;
|
|
198
236
|
/**
|
|
199
237
|
* Supported message body render orders for mixed text and structured blocks.
|
|
200
238
|
*/
|
package/dist/index.js
CHANGED
|
@@ -108,6 +108,38 @@ var resolveSessionTitleFromMessage = (message) => {
|
|
|
108
108
|
var mergeStreamingBlocks = (existingBlocks, incomingBlocks) => {
|
|
109
109
|
const nextBlocks = [...existingBlocks ?? []];
|
|
110
110
|
incomingBlocks.forEach((incomingBlock) => {
|
|
111
|
+
if (incomingBlock.type === "custom" && incomingBlock.blockKey) {
|
|
112
|
+
const mergePolicy = incomingBlock.mergePolicy ?? "append";
|
|
113
|
+
if (mergePolicy !== "append") {
|
|
114
|
+
const existingIndex2 = nextBlocks.findIndex(
|
|
115
|
+
(block) => block.type === "custom" && block.blockKey === incomingBlock.blockKey
|
|
116
|
+
);
|
|
117
|
+
if (existingIndex2 !== -1) {
|
|
118
|
+
if (mergePolicy === "replace") {
|
|
119
|
+
nextBlocks[existingIndex2] = incomingBlock;
|
|
120
|
+
}
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
nextBlocks.push(incomingBlock);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (incomingBlock.type === "questionnaire" && incomingBlock.questionnaire.blockKey) {
|
|
128
|
+
const mergePolicy = incomingBlock.questionnaire.mergePolicy ?? "append";
|
|
129
|
+
if (mergePolicy !== "append") {
|
|
130
|
+
const existingIndex2 = nextBlocks.findIndex(
|
|
131
|
+
(block) => block.type === "questionnaire" && block.questionnaire.blockKey === incomingBlock.questionnaire.blockKey
|
|
132
|
+
);
|
|
133
|
+
if (existingIndex2 !== -1) {
|
|
134
|
+
if (mergePolicy === "replace") {
|
|
135
|
+
nextBlocks[existingIndex2] = incomingBlock;
|
|
136
|
+
}
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
nextBlocks.push(incomingBlock);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
111
143
|
if (incomingBlock.type !== "questionnaire") {
|
|
112
144
|
nextBlocks.push(incomingBlock);
|
|
113
145
|
return;
|
|
@@ -1008,9 +1040,9 @@ var getTimelineBlockKey = (block, index) => {
|
|
|
1008
1040
|
case "result_summary":
|
|
1009
1041
|
return `${index}:result_summary:${block.summary.summaryId}:${block.summary.status}`;
|
|
1010
1042
|
case "questionnaire":
|
|
1011
|
-
return `${index}:questionnaire:${block.questionnaire.questionnaireId}`;
|
|
1043
|
+
return block.questionnaire.blockKey ? `questionnaire:${block.questionnaire.blockKey}` : `${index}:questionnaire:${block.questionnaire.questionnaireId}`;
|
|
1012
1044
|
case "custom":
|
|
1013
|
-
return `${index}:custom:${block.kind}:${stringifyTimelineKeyPart(block.data)}`;
|
|
1045
|
+
return block.blockKey ? `custom:${block.blockKey}` : `${index}:custom:${block.kind}:${stringifyTimelineKeyPart(block.data)}`;
|
|
1014
1046
|
default:
|
|
1015
1047
|
return null;
|
|
1016
1048
|
}
|
|
@@ -1656,6 +1688,7 @@ var QuestionnaireCardInner = ({
|
|
|
1656
1688
|
try {
|
|
1657
1689
|
await onSubmit?.({
|
|
1658
1690
|
questionnaireId: questionnaire.questionnaireId,
|
|
1691
|
+
...questionnaire.blockKey ? { blockKey: questionnaire.blockKey } : {},
|
|
1659
1692
|
answers: normalizedAnswers,
|
|
1660
1693
|
content: contentLines.join("\n")
|
|
1661
1694
|
});
|
|
@@ -2467,7 +2500,7 @@ var ChatMessageItemView = ({
|
|
|
2467
2500
|
sourceMessageId: message.id
|
|
2468
2501
|
}) : void 0
|
|
2469
2502
|
}
|
|
2470
|
-
) }, `questionnaire-${index}`);
|
|
2503
|
+
) }, block.questionnaire.blockKey ?? `questionnaire-${index}`);
|
|
2471
2504
|
case "custom":
|
|
2472
2505
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: renderMessageBlock?.({
|
|
2473
2506
|
block,
|
package/dist/index.mjs
CHANGED
|
@@ -61,6 +61,38 @@ var resolveSessionTitleFromMessage = (message) => {
|
|
|
61
61
|
var mergeStreamingBlocks = (existingBlocks, incomingBlocks) => {
|
|
62
62
|
const nextBlocks = [...existingBlocks ?? []];
|
|
63
63
|
incomingBlocks.forEach((incomingBlock) => {
|
|
64
|
+
if (incomingBlock.type === "custom" && incomingBlock.blockKey) {
|
|
65
|
+
const mergePolicy = incomingBlock.mergePolicy ?? "append";
|
|
66
|
+
if (mergePolicy !== "append") {
|
|
67
|
+
const existingIndex2 = nextBlocks.findIndex(
|
|
68
|
+
(block) => block.type === "custom" && block.blockKey === incomingBlock.blockKey
|
|
69
|
+
);
|
|
70
|
+
if (existingIndex2 !== -1) {
|
|
71
|
+
if (mergePolicy === "replace") {
|
|
72
|
+
nextBlocks[existingIndex2] = incomingBlock;
|
|
73
|
+
}
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
nextBlocks.push(incomingBlock);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (incomingBlock.type === "questionnaire" && incomingBlock.questionnaire.blockKey) {
|
|
81
|
+
const mergePolicy = incomingBlock.questionnaire.mergePolicy ?? "append";
|
|
82
|
+
if (mergePolicy !== "append") {
|
|
83
|
+
const existingIndex2 = nextBlocks.findIndex(
|
|
84
|
+
(block) => block.type === "questionnaire" && block.questionnaire.blockKey === incomingBlock.questionnaire.blockKey
|
|
85
|
+
);
|
|
86
|
+
if (existingIndex2 !== -1) {
|
|
87
|
+
if (mergePolicy === "replace") {
|
|
88
|
+
nextBlocks[existingIndex2] = incomingBlock;
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
nextBlocks.push(incomingBlock);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
64
96
|
if (incomingBlock.type !== "questionnaire") {
|
|
65
97
|
nextBlocks.push(incomingBlock);
|
|
66
98
|
return;
|
|
@@ -961,9 +993,9 @@ var getTimelineBlockKey = (block, index) => {
|
|
|
961
993
|
case "result_summary":
|
|
962
994
|
return `${index}:result_summary:${block.summary.summaryId}:${block.summary.status}`;
|
|
963
995
|
case "questionnaire":
|
|
964
|
-
return `${index}:questionnaire:${block.questionnaire.questionnaireId}`;
|
|
996
|
+
return block.questionnaire.blockKey ? `questionnaire:${block.questionnaire.blockKey}` : `${index}:questionnaire:${block.questionnaire.questionnaireId}`;
|
|
965
997
|
case "custom":
|
|
966
|
-
return `${index}:custom:${block.kind}:${stringifyTimelineKeyPart(block.data)}`;
|
|
998
|
+
return block.blockKey ? `custom:${block.blockKey}` : `${index}:custom:${block.kind}:${stringifyTimelineKeyPart(block.data)}`;
|
|
967
999
|
default:
|
|
968
1000
|
return null;
|
|
969
1001
|
}
|
|
@@ -1609,6 +1641,7 @@ var QuestionnaireCardInner = ({
|
|
|
1609
1641
|
try {
|
|
1610
1642
|
await onSubmit?.({
|
|
1611
1643
|
questionnaireId: questionnaire.questionnaireId,
|
|
1644
|
+
...questionnaire.blockKey ? { blockKey: questionnaire.blockKey } : {},
|
|
1612
1645
|
answers: normalizedAnswers,
|
|
1613
1646
|
content: contentLines.join("\n")
|
|
1614
1647
|
});
|
|
@@ -2420,7 +2453,7 @@ var ChatMessageItemView = ({
|
|
|
2420
2453
|
sourceMessageId: message.id
|
|
2421
2454
|
}) : void 0
|
|
2422
2455
|
}
|
|
2423
|
-
) }, `questionnaire-${index}`);
|
|
2456
|
+
) }, block.questionnaire.blockKey ?? `questionnaire-${index}`);
|
|
2424
2457
|
case "custom":
|
|
2425
2458
|
return /* @__PURE__ */ jsx8(Fragment, { children: renderMessageBlock?.({
|
|
2426
2459
|
block,
|