@sendevia/pi-ask-author 1.0.6 → 1.1.1

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.
@@ -5,14 +5,29 @@
5
5
  * 核心架构特性:
6
6
  * - 容错范围:JSON 串包裹 / `raw` 包装键 / 字段别名 / 纯字符串选项 / 空选项兜底
7
7
  * - 白名单收敛:产物仅含 `RawParams` 声明字段(丢弃未知键),保障宿主 Schema 校验通过
8
+ * - 推演载荷清洗:`sanitizeExpansionPayload` 丢弃引用未知题目的选项追加、重复标签、与既有 ID 冲突的新题目与无选项题目
8
9
  * - 防御纵深:本层做类型收敛 / 别名映射 / 结构规整 / 区间兜底,模型层再幂等兜底一次
9
10
  *
10
- * 依赖方向:sanitize.ts → format.ts / texts.ts / schema.ts(类型);仅由 index.ts 装配
11
+ * 依赖方向:sanitize.ts → format.ts / layout.ts / texts.ts / schema.ts(类型);被 index / expansion / tool-card 消费
11
12
  */
12
- import type { RawParams } from "./schema.js";
13
+ import type { ExpansionPayload, RawParams } from "./schema.js";
13
14
  /**
14
15
  * 入参防御性清洗(`prepareArguments` 钩子);容错面见文件头,各字段先收敛为本地强类型 `const` 再组装为显式白名单产物
15
16
  * @param args - 工具调用原始入参(不可信边界)
16
17
  * @returns 仅含 Schema 声明字段的 `RawParams` 白名单对象;输入完全不可辨识时仅返回兜底 `formTitle`
17
18
  */
18
19
  export declare function sanitizeAskAuthorArgs(args: unknown): RawParams;
20
+ /** 推演载荷的归集上下文:表单当前已声明的题目 ID 与各题已有选项标签 */
21
+ export interface ExpansionContext {
22
+ /** 已声明的题目 ID(按题目顺序) */
23
+ readonly questionIds: readonly string[];
24
+ /** 题目 ID → 已有选项标签 */
25
+ readonly optionLabels: ReadonlyMap<string, readonly string[]>;
26
+ }
27
+ /**
28
+ * 规整推演模型的回复载荷(不可信边界):丢弃引用未知题目的选项追加、与既有标签重复的选项以及与既有题目 ID 冲突的新题目
29
+ * @param value - 已解析的回复对象(非对象时视为无新增)
30
+ * @param context - 表单当前已声明的题目与选项标签
31
+ * @returns 仅含合法追加项的推演载荷;全部条目被过滤时返回空载荷(表单停止增长)
32
+ */
33
+ export declare function sanitizeExpansionPayload(value: unknown, context: ExpansionContext): ExpansionPayload;
package/dist/schema.d.ts CHANGED
@@ -6,12 +6,22 @@
6
6
  * - 字段名称、可选性与区间约束(`minItems` / `maxItems` / `minimum`)仅在 TypeBox 定义一次,运行时类型经 `Static<typeof>` 派生
7
7
  * - 默认值不写入 Schema:题目内字段由 `sanitize.ts` 规整时填入(`multiSelect`→false、`allowCustom`→true),模型层再按同一语义兜底
8
8
  * - LLM 端字段描述保持单句浓缩英文(取自 `TEXTS.schema`)
9
+ * - 推演载荷(`ExpansionPayload` / `OptionAddition`)的接口类型也在此声明,供 sanitize / model / expansion 共用
9
10
  *
10
- * 依赖方向:schema.ts → typebox / texts.ts(上限常量与字段描述);被 sanitize / model / index 消费
11
+ * 依赖方向:schema.ts → typebox / layout.ts / texts.ts(上限常量与字段描述);被 sanitize / model / expansion / index 消费
11
12
  */
12
13
  import { Type, type Static } from "typebox";
14
+ /** 显示条件参数 Schema:引用更早题目的作答状态,决定本题或本选项是否出现 */
15
+ export declare const ShowIfConditionSchema: Type.TObject<{
16
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
17
+ questionId: Type.TString;
18
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
19
+ option: Type.TOptional<Type.TString>;
20
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
21
+ answered: Type.TOptional<Type.TBoolean>;
22
+ }>;
13
23
  /** 单个候选选项的参数 Schema */
14
- declare const OptionSchema: Type.TObject<{
24
+ export declare const OptionSchema: Type.TObject<{
15
25
  /** 选项简短标题/行动标签(必须填写;缺失时经 `sanitize.ts` → `model.ts` 两级兜底为自动占位标签) */
16
26
  label: Type.TString;
17
27
  /** 情节推演后果或设定阐述(可选) */
@@ -20,13 +30,31 @@ declare const OptionSchema: Type.TObject<{
20
30
  preview: Type.TOptional<Type.TString>;
21
31
  /** 该选项专属补充说明的占位引导文案(可选) */
22
32
  customPlaceholder: Type.TOptional<Type.TString>;
33
+ /** 该选项的显示条件(可选;不成立时不展示,选中态同样不计入答卷) */
34
+ showIf: Type.TOptional<Type.TUnion<[Type.TObject<{
35
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
36
+ questionId: Type.TString;
37
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
38
+ option: Type.TOptional<Type.TString>;
39
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
40
+ answered: Type.TOptional<Type.TBoolean>;
41
+ }>, Type.TArray<Type.TObject<{
42
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
43
+ questionId: Type.TString;
44
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
45
+ option: Type.TOptional<Type.TString>;
46
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
47
+ answered: Type.TOptional<Type.TBoolean>;
48
+ }>>]>>;
23
49
  }>;
24
50
  /** 单个问题的参数 Schema(批量问卷与平铺模式共用) */
25
- declare const QuestionSchema: Type.TObject<{
51
+ export declare const QuestionSchema: Type.TObject<{
26
52
  /** 题目唯一标识符(可选;缺省由模型层按顺序生成,跨题重复由模型层去重) */
27
53
  id: Type.TOptional<Type.TString>;
28
54
  /** 题目标题(必须填写;缺失时两级兜底为自动占位标题) */
29
55
  title: Type.TString;
56
+ /** Tab 栏短标签(可选;缺省时 Tab 栏显示题号) */
57
+ tabLabel: Type.TOptional<Type.TString>;
30
58
  /** 题目背景与语境(可选) */
31
59
  description: Type.TOptional<Type.TString>;
32
60
  /** 是否允许多选(可选;默认 false,即单选) */
@@ -47,11 +75,58 @@ declare const QuestionSchema: Type.TObject<{
47
75
  preview: Type.TOptional<Type.TString>;
48
76
  /** 该选项专属补充说明的占位引导文案(可选) */
49
77
  customPlaceholder: Type.TOptional<Type.TString>;
78
+ /** 该选项的显示条件(可选;不成立时不展示,选中态同样不计入答卷) */
79
+ showIf: Type.TOptional<Type.TUnion<[Type.TObject<{
80
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
81
+ questionId: Type.TString;
82
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
83
+ option: Type.TOptional<Type.TString>;
84
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
85
+ answered: Type.TOptional<Type.TBoolean>;
86
+ }>, Type.TArray<Type.TObject<{
87
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
88
+ questionId: Type.TString;
89
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
90
+ option: Type.TOptional<Type.TString>;
91
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
92
+ answered: Type.TOptional<Type.TBoolean>;
93
+ }>>]>>;
50
94
  }>>;
51
95
  /** 是否允许自由补充说明(可选;默认 true) */
52
96
  allowCustom: Type.TOptional<Type.TBoolean>;
53
97
  /** 题目整体补充说明的占位引导词(可选) */
54
98
  customPlaceholder: Type.TOptional<Type.TString>;
99
+ /** 该题目的显示条件(可选;不成立时不展示,也不计入答卷) */
100
+ showIf: Type.TOptional<Type.TUnion<[Type.TObject<{
101
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
102
+ questionId: Type.TString;
103
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
104
+ option: Type.TOptional<Type.TString>;
105
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
106
+ answered: Type.TOptional<Type.TBoolean>;
107
+ }>, Type.TArray<Type.TObject<{
108
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
109
+ questionId: Type.TString;
110
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
111
+ option: Type.TOptional<Type.TString>;
112
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
113
+ answered: Type.TOptional<Type.TBoolean>;
114
+ }>>]>>;
115
+ }>;
116
+ /** 推演题目的插入位置预设:跟随触发题目 / 排到队尾 / 指定题目之后 */
117
+ export declare const InsertPositionSchema: Type.TUnion<[Type.TLiteral<"follow">, Type.TLiteral<"tail">, Type.TObject<{
118
+ after: Type.TString;
119
+ }>]>;
120
+ /** 实时推演参数 Schema:作者确认答案后由同一模型追加题目与选项 */
121
+ export declare const ExpansionSchema: Type.TObject<{
122
+ /** 推演后的题目总量上限(含已声明的题目) */
123
+ maxQuestions: Type.TOptional<Type.TInteger>;
124
+ /** 长期生效的推演方向指示 */
125
+ guidance: Type.TOptional<Type.TString>;
126
+ /** 推演题目的插入位置(缺省为跟随触发题目) */
127
+ insert: Type.TOptional<Type.TUnion<[Type.TLiteral<"follow">, Type.TLiteral<"tail">, Type.TObject<{
128
+ after: Type.TString;
129
+ }>]>>;
55
130
  }>;
56
131
  /** `ask_author` 工具完整参数 Schema(必须填写 `formTitle`;批量问卷传递 `questions`,单题平铺传递顶层 `question` + `options`) */
57
132
  export declare const AskAuthorParams: Type.TObject<{
@@ -59,12 +134,25 @@ export declare const AskAuthorParams: Type.TObject<{
59
134
  formTitle: Type.TString;
60
135
  /** 问卷全局背景或前述情境(可选;平铺单题模式下同时充当该题描述) */
61
136
  description: Type.TOptional<Type.TString>;
137
+ /** 实时推演开关(可选;开启后作者每次确认答案都追加后续题目与选项) */
138
+ expansion: Type.TOptional<Type.TObject<{
139
+ /** 推演后的题目总量上限(含已声明的题目) */
140
+ maxQuestions: Type.TOptional<Type.TInteger>;
141
+ /** 长期生效的推演方向指示 */
142
+ guidance: Type.TOptional<Type.TString>;
143
+ /** 推演题目的插入位置(缺省为跟随触发题目) */
144
+ insert: Type.TOptional<Type.TUnion<[Type.TLiteral<"follow">, Type.TLiteral<"tail">, Type.TObject<{
145
+ after: Type.TString;
146
+ }>]>>;
147
+ }>>;
62
148
  /** 关联多题批量问卷列表(可选;批量模式使用,上限 `MAX_QUESTIONS` 题) */
63
149
  questions: Type.TOptional<Type.TArray<Type.TObject<{
64
150
  /** 题目唯一标识符(可选;缺省由模型层按顺序生成,跨题重复由模型层去重) */
65
151
  id: Type.TOptional<Type.TString>;
66
152
  /** 题目标题(必须填写;缺失时两级兜底为自动占位标题) */
67
153
  title: Type.TString;
154
+ /** Tab 栏短标签(可选;缺省时 Tab 栏显示题号) */
155
+ tabLabel: Type.TOptional<Type.TString>;
68
156
  /** 题目背景与语境(可选) */
69
157
  description: Type.TOptional<Type.TString>;
70
158
  /** 是否允许多选(可选;默认 false,即单选) */
@@ -85,11 +173,43 @@ export declare const AskAuthorParams: Type.TObject<{
85
173
  preview: Type.TOptional<Type.TString>;
86
174
  /** 该选项专属补充说明的占位引导文案(可选) */
87
175
  customPlaceholder: Type.TOptional<Type.TString>;
176
+ /** 该选项的显示条件(可选;不成立时不展示,选中态同样不计入答卷) */
177
+ showIf: Type.TOptional<Type.TUnion<[Type.TObject<{
178
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
179
+ questionId: Type.TString;
180
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
181
+ option: Type.TOptional<Type.TString>;
182
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
183
+ answered: Type.TOptional<Type.TBoolean>;
184
+ }>, Type.TArray<Type.TObject<{
185
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
186
+ questionId: Type.TString;
187
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
188
+ option: Type.TOptional<Type.TString>;
189
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
190
+ answered: Type.TOptional<Type.TBoolean>;
191
+ }>>]>>;
88
192
  }>>;
89
193
  /** 是否允许自由补充说明(可选;默认 true) */
90
194
  allowCustom: Type.TOptional<Type.TBoolean>;
91
195
  /** 题目整体补充说明的占位引导词(可选) */
92
196
  customPlaceholder: Type.TOptional<Type.TString>;
197
+ /** 该题目的显示条件(可选;不成立时不展示,也不计入答卷) */
198
+ showIf: Type.TOptional<Type.TUnion<[Type.TObject<{
199
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
200
+ questionId: Type.TString;
201
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
202
+ option: Type.TOptional<Type.TString>;
203
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
204
+ answered: Type.TOptional<Type.TBoolean>;
205
+ }>, Type.TArray<Type.TObject<{
206
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
207
+ questionId: Type.TString;
208
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
209
+ option: Type.TOptional<Type.TString>;
210
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
211
+ answered: Type.TOptional<Type.TBoolean>;
212
+ }>>]>>;
93
213
  }>>>;
94
214
  /** 单题平铺模式题目标题(可选;仅在携带非空 `options` 时参与选题,缺省回退 `TEXTS.fallbacks.defaultQuestionTitle`) */
95
215
  question: Type.TOptional<Type.TString>;
@@ -111,6 +231,22 @@ export declare const AskAuthorParams: Type.TObject<{
111
231
  preview: Type.TOptional<Type.TString>;
112
232
  /** 该选项专属补充说明的占位引导文案(可选) */
113
233
  customPlaceholder: Type.TOptional<Type.TString>;
234
+ /** 该选项的显示条件(可选;不成立时不展示,选中态同样不计入答卷) */
235
+ showIf: Type.TOptional<Type.TUnion<[Type.TObject<{
236
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
237
+ questionId: Type.TString;
238
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
239
+ option: Type.TOptional<Type.TString>;
240
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
241
+ answered: Type.TOptional<Type.TBoolean>;
242
+ }>, Type.TArray<Type.TObject<{
243
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
244
+ questionId: Type.TString;
245
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
246
+ option: Type.TOptional<Type.TString>;
247
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
248
+ answered: Type.TOptional<Type.TBoolean>;
249
+ }>>]>>;
114
250
  }>>>;
115
251
  /** 单题平铺模式是否允许自由补充说明(可选;默认 true) */
116
252
  allowCustom: Type.TOptional<Type.TBoolean>;
@@ -126,4 +262,25 @@ export type RawParams = Static<typeof AskAuthorParams>;
126
262
  export type QuestionOption = Static<typeof OptionSchema>;
127
263
  /** 单个问题的运行时类型(由 `QuestionSchema` 经 `Static<typeof>` 派生,批量与平铺共用) */
128
264
  export type QuestionInput = Static<typeof QuestionSchema>;
129
- export {};
265
+ /** 单个显示条件的运行时类型(由 `ShowIfConditionSchema` 经 `Static<typeof>` 派生) */
266
+ export type VisibilityConditionInput = Static<typeof ShowIfConditionSchema>;
267
+ /** `showIf` 字段的运行时类型:单个条件或条件数组 */
268
+ export type ShowIfInput = VisibilityConditionInput | VisibilityConditionInput[];
269
+ /** 实时推演配置的运行时类型(由 `ExpansionSchema` 经 `Static<>` 派生) */
270
+ export type ExpansionConfig = Static<typeof ExpansionSchema>;
271
+ /** 推演题目插入位置的运行时类型:预设字符串或指定题目之后的锚点 */
272
+ export type InsertPosition = Static<typeof InsertPositionSchema>;
273
+ /** 推演向既有题目追加的一组选项 */
274
+ export interface OptionAddition {
275
+ /** 目标题目的 ID(必须是表单中已存在的题目) */
276
+ readonly questionId: string;
277
+ /** 待追加的选项(标签与既有选项不重复) */
278
+ readonly options: QuestionOption[];
279
+ }
280
+ /** 一次推演的产出:待追加的新题目与向既有题目追加的选项 */
281
+ export interface ExpansionPayload {
282
+ /** 追加到题目列表末尾的新题目 */
283
+ readonly questions: QuestionInput[];
284
+ /** 向既有题目追加的选项 */
285
+ readonly optionAdditions: OptionAddition[];
286
+ }