@dudousxd/nestjs-agent-core 0.36.0 → 0.37.0

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.cjs CHANGED
@@ -25,6 +25,7 @@ __export(src_exports, {
25
25
  AGENT_ACTOR_RESOLVER: () => AGENT_ACTOR_RESOLVER,
26
26
  AGENT_APPROVAL_PORT: () => AGENT_APPROVAL_PORT,
27
27
  AGENT_ATTACHMENT_STAGING: () => AGENT_ATTACHMENT_STAGING,
28
+ AGENT_CONFIRM_TOKEN_STORE: () => AGENT_CONFIRM_TOKEN_STORE,
28
29
  AGENT_DEPS_FACTORY: () => AGENT_DEPS_FACTORY,
29
30
  AGENT_DIAGNOSTIC_EVENTS: () => AGENT_DIAGNOSTIC_EVENTS,
30
31
  AGENT_DURABLE_RUNNER: () => AGENT_DURABLE_RUNNER,
@@ -54,7 +55,10 @@ __export(src_exports, {
54
55
  ASK_TOOL_NAME: () => ASK_TOOL_NAME,
55
56
  AgentRegistry: () => AgentRegistry,
56
57
  AgentStreamError: () => AgentStreamError,
58
+ CONFIRM_JSON_SCHEMA_PROPERTIES: () => CONFIRM_JSON_SCHEMA_PROPERTIES,
57
59
  ClosedRolesPolicy: () => ClosedRolesPolicy,
60
+ ConfirmTokenError: () => ConfirmTokenError,
61
+ DEFAULT_CONFIRM_TTL_MS: () => DEFAULT_CONFIRM_TTL_MS,
58
62
  DEFAULT_HISTORY_SUMMARY_INSTRUCTION: () => DEFAULT_HISTORY_SUMMARY_INSTRUCTION,
59
63
  DEFAULT_INCREMENTAL_LOOKBACK_CHARS: () => DEFAULT_INCREMENTAL_LOOKBACK_CHARS,
60
64
  DEFAULT_INTAKE_PREAMBLE: () => DEFAULT_INTAKE_PREAMBLE,
@@ -70,6 +74,7 @@ __export(src_exports, {
70
74
  ELICITATION_INPUT_TYPES: () => ELICITATION_INPUT_TYPES,
71
75
  GLOBAL_SCOPE: () => GLOBAL_SCOPE,
72
76
  InMemoryAgentStore: () => InMemoryAgentStore,
77
+ InMemoryConfirmTokenStore: () => InMemoryConfirmTokenStore,
73
78
  MAX_ASK_QUESTIONS: () => MAX_ASK_QUESTIONS,
74
79
  OutputRejectedError: () => OutputRejectedError,
75
80
  ProcessorFailedError: () => ProcessorFailedError,
@@ -83,6 +88,7 @@ __export(src_exports, {
83
88
  RUN_NOT_ACTIVE_MESSAGE: () => RUN_NOT_ACTIVE_MESSAGE,
84
89
  RUN_NO_LONGER_RUNNING: () => RUN_NO_LONGER_RUNNING,
85
90
  RunCancelledError: () => RunCancelledError,
91
+ SCHEMA_EXTENSION: () => SCHEMA_EXTENSION,
86
92
  SKILL_TOOL_DESCRIPTION: () => SKILL_TOOL_DESCRIPTION,
87
93
  SKILL_TOOL_NAME: () => SKILL_TOOL_NAME,
88
94
  StructuredOutputError: () => StructuredOutputError,
@@ -105,8 +111,10 @@ __export(src_exports, {
105
111
  buildMemoryBlock: () => buildMemoryBlock,
106
112
  buildSkillsBlock: () => buildSkillsBlock,
107
113
  canActorUseTool: () => canActorUseTool,
114
+ canonicalJson: () => canonicalJson,
108
115
  closeEmptyRoles: () => closeEmptyRoles,
109
116
  compositeSkillProvider: () => compositeSkillProvider,
117
+ confirmTokenExpiry: () => confirmTokenExpiry,
110
118
  createFrameBuffer: () => createFrameBuffer,
111
119
  createIncrementalGate: () => createIncrementalGate,
112
120
  createNoopEmitUi: () => createNoopEmitUi,
@@ -116,6 +124,7 @@ __export(src_exports, {
116
124
  decodeStreamEvent: () => decodeStreamEvent,
117
125
  defaultCanDecide: () => defaultCanDecide,
118
126
  defaultScopeResolver: () => defaultScopeResolver,
127
+ defineConfirmedTool: () => defineConfirmedTool,
119
128
  detachedDelivered: () => detachedDelivered,
120
129
  detachedStarted: () => detachedStarted,
121
130
  detachedUnsettled: () => detachedUnsettled,
@@ -132,6 +141,7 @@ __export(src_exports, {
132
141
  findCatalogModel: () => findCatalogModel,
133
142
  gateFollowUps: () => gateFollowUps,
134
143
  gateTail: () => gateTail,
144
+ hashConfirmToken: () => hashConfirmToken,
135
145
  invokeWithTransientRetry: () => invokeWithTransientRetry,
136
146
  isChatQueueStore: () => isChatQueueStore,
137
147
  isControlFlowSignal: () => isControlFlowSignal,
@@ -184,12 +194,14 @@ __export(src_exports, {
184
194
  runAgentLoop: () => runAgentLoop,
185
195
  runInputProcessors: () => runInputProcessors,
186
196
  runOutputProcessors: () => runOutputProcessors,
197
+ schemaExtensionOf: () => schemaExtensionOf,
187
198
  seedModelPrices: () => seedModelPrices,
188
199
  settleAll: () => settleAll,
189
200
  settleDanglingToolCalls: () => settleDanglingToolCalls,
190
201
  settleDeadRun: () => settleDeadRun,
191
202
  settleElicitation: () => settleElicitation,
192
203
  settleUnsettledDelegation: () => settleUnsettledDelegation,
204
+ signConfirmToken: () => signConfirmToken,
193
205
  skillInputSchema: () => skillInputSchema,
194
206
  skillToolDefinition: () => skillToolDefinition,
195
207
  skillWriteVerdict: () => skillWriteVerdict,
@@ -208,8 +220,10 @@ __export(src_exports, {
208
220
  validateElicitationAnswer: () => validateElicitationAnswer,
209
221
  validateElicitationValue: () => validateElicitationValue,
210
222
  validateStructured: () => validateStructured,
223
+ verifyConfirmToken: () => verifyConfirmToken,
211
224
  windowHistory: () => windowHistory,
212
225
  withAskTool: () => withAskTool,
226
+ withConfirmFields: () => withConfirmFields,
213
227
  withMemoryTool: () => withMemoryTool,
214
228
  withSelectedModel: () => withSelectedModel,
215
229
  withSkillTool: () => withSkillTool,
@@ -246,6 +260,7 @@ var AGENT_APPROVAL_PORT = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:app
246
260
  var AGENT_SKILLS = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:skills");
247
261
  var AGENT_MEMORY = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:memory");
248
262
  var AGENT_SKILL_SOURCES = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:skill-sources");
263
+ var AGENT_CONFIRM_TOKEN_STORE = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:confirm-token-store");
249
264
 
250
265
  // src/spi/model-catalog.ts
251
266
  function staticModelCatalog(view) {
@@ -6006,12 +6021,322 @@ var InMemoryAgentStore = class {
6006
6021
  };
6007
6022
  }
6008
6023
  };
6024
+
6025
+ // src/confirm-token.ts
6026
+ var import_node_crypto2 = require("crypto");
6027
+ var DEFAULT_CONFIRM_TTL_MS = 15 * 60 * 1e3;
6028
+ function canonicalJson(value) {
6029
+ if (value === void 0) return "null";
6030
+ if (value === null || typeof value !== "object") return JSON.stringify(value) ?? "null";
6031
+ if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
6032
+ if (typeof value.toJSON === "function") {
6033
+ return canonicalJson(value.toJSON());
6034
+ }
6035
+ const entries = Object.entries(value).filter(([, entry]) => entry !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
6036
+ return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${canonicalJson(entry)}`).join(",")}}`;
6037
+ }
6038
+ __name(canonicalJson, "canonicalJson");
6039
+ function signature(subject, expiresAt, secret) {
6040
+ if (secret === "") {
6041
+ throw new Error("confirm token: the secret is empty");
6042
+ }
6043
+ return (0, import_node_crypto2.createHmac)("sha256", secret).update(canonicalJson([
6044
+ "agent-confirm",
6045
+ subject.tool,
6046
+ subject.actorId,
6047
+ subject.tenantRef ?? "",
6048
+ expiresAt,
6049
+ subject.args
6050
+ ])).digest("base64url");
6051
+ }
6052
+ __name(signature, "signature");
6053
+ function signConfirmToken(subject, options) {
6054
+ return `${options.expiresAt}.${signature(subject, options.expiresAt, options.secret)}`;
6055
+ }
6056
+ __name(signConfirmToken, "signConfirmToken");
6057
+ function confirmTokenExpiry(token) {
6058
+ const separator = token.indexOf(".");
6059
+ if (separator <= 0) return void 0;
6060
+ const expiresAt = Number(token.slice(0, separator));
6061
+ return Number.isSafeInteger(expiresAt) && expiresAt > 0 ? expiresAt : void 0;
6062
+ }
6063
+ __name(confirmTokenExpiry, "confirmTokenExpiry");
6064
+ function verifyConfirmToken(token, subject, options) {
6065
+ if (typeof token !== "string") return false;
6066
+ const expiresAt = confirmTokenExpiry(token);
6067
+ if (expiresAt === void 0 || expiresAt < (options.now ?? Date.now())) return false;
6068
+ const expected = Buffer.from(signature(subject, expiresAt, options.secret));
6069
+ const given = Buffer.from(token.slice(token.indexOf(".") + 1));
6070
+ return expected.length === given.length && (0, import_node_crypto2.timingSafeEqual)(expected, given);
6071
+ }
6072
+ __name(verifyConfirmToken, "verifyConfirmToken");
6073
+ function hashConfirmToken(token) {
6074
+ return (0, import_node_crypto2.createHash)("sha256").update(token).digest("hex");
6075
+ }
6076
+ __name(hashConfirmToken, "hashConfirmToken");
6077
+ var InMemoryConfirmTokenStore = class {
6078
+ static {
6079
+ __name(this, "InMemoryConfirmTokenStore");
6080
+ }
6081
+ claims = /* @__PURE__ */ new Map();
6082
+ async claim(input) {
6083
+ await this.purgeExpired();
6084
+ if (this.claims.has(input.hash)) return false;
6085
+ this.claims.set(input.hash, {
6086
+ ...input
6087
+ });
6088
+ return true;
6089
+ }
6090
+ async release(hash) {
6091
+ this.claims.delete(hash);
6092
+ }
6093
+ async purgeExpired(now = Date.now()) {
6094
+ let purged = 0;
6095
+ for (const [hash, claim] of this.claims) {
6096
+ if (claim.expiresAt < now) {
6097
+ this.claims.delete(hash);
6098
+ purged += 1;
6099
+ }
6100
+ }
6101
+ return purged;
6102
+ }
6103
+ /** How many tokens are currently marked as spent. */
6104
+ get size() {
6105
+ return this.claims.size;
6106
+ }
6107
+ };
6108
+
6109
+ // src/confirmed-tool.ts
6110
+ var DEFAULT_MESSAGES = {
6111
+ confirm: 'Nothing was written. Show this preview to the user and ask them to confirm. To commit, call this tool again with the SAME arguments plus "confirm": true and this "confirmToken" (valid for {minutes} minutes).',
6112
+ invalid: 'Invalid or expired confirmation: nothing was written. Call the tool without "confirm" to get a fresh preview, then confirm with the "confirmToken" it returns, without changing the arguments.',
6113
+ used: "This preview was already confirmed: nothing was written again. To repeat the operation, ask for a new preview."
6114
+ };
6115
+ var ConfirmTokenError = class extends Error {
6116
+ static {
6117
+ __name(this, "ConfirmTokenError");
6118
+ }
6119
+ reason;
6120
+ constructor(reason, message) {
6121
+ super(message), this.reason = reason;
6122
+ this.name = "ConfirmTokenError";
6123
+ }
6124
+ };
6125
+ var CONFIRM_JSON_SCHEMA_PROPERTIES = {
6126
+ confirm: {
6127
+ type: "boolean",
6128
+ description: "Omit to get a preview (nothing is written). Send true, with confirmToken, to commit."
6129
+ },
6130
+ confirmToken: {
6131
+ type: "string",
6132
+ description: "The confirmToken the preview returned. Required when confirm is true."
6133
+ }
6134
+ };
6135
+ var SCHEMA_EXTENSION = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:schema-extension");
6136
+ function schemaExtensionOf(schema) {
6137
+ const extension = schema[SCHEMA_EXTENSION];
6138
+ return typeof extension === "object" && extension !== null ? extension : void 0;
6139
+ }
6140
+ __name(schemaExtensionOf, "schemaExtensionOf");
6141
+ function isRecord(value) {
6142
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6143
+ }
6144
+ __name(isRecord, "isRecord");
6145
+ function splitConfirm(input) {
6146
+ if (!isRecord(input)) return {
6147
+ args: input,
6148
+ fields: {}
6149
+ };
6150
+ const { confirm, confirmToken, ...args } = input;
6151
+ return {
6152
+ args,
6153
+ fields: {
6154
+ ...typeof confirm === "boolean" ? {
6155
+ confirm
6156
+ } : {},
6157
+ ...typeof confirmToken === "string" ? {
6158
+ confirmToken
6159
+ } : {}
6160
+ }
6161
+ };
6162
+ }
6163
+ __name(splitConfirm, "splitConfirm");
6164
+ function jsonSchemaInputOf(schema) {
6165
+ const standard = schema["~standard"];
6166
+ const input = standard.jsonSchema?.input;
6167
+ return typeof input === "function" ? (options) => input.call(standard.jsonSchema, options) : void 0;
6168
+ }
6169
+ __name(jsonSchemaInputOf, "jsonSchemaInputOf");
6170
+ function withConfirmFields(schema) {
6171
+ const inner = schema["~standard"];
6172
+ const innerJsonSchema = jsonSchemaInputOf(schema);
6173
+ const describe = /* @__PURE__ */ __name((options) => {
6174
+ const base = innerJsonSchema?.(options) ?? {
6175
+ additionalProperties: true
6176
+ };
6177
+ return {
6178
+ ...base,
6179
+ type: "object",
6180
+ properties: {
6181
+ ...isRecord(base.properties) ? base.properties : {},
6182
+ ...CONFIRM_JSON_SCHEMA_PROPERTIES
6183
+ }
6184
+ };
6185
+ }, "describe");
6186
+ const wrapped = {
6187
+ [SCHEMA_EXTENSION]: {
6188
+ base: schema,
6189
+ properties: CONFIRM_JSON_SCHEMA_PROPERTIES
6190
+ },
6191
+ "~standard": {
6192
+ version: 1,
6193
+ vendor: "@dudousxd/nestjs-agent",
6194
+ validate: /* @__PURE__ */ __name(async (value) => {
6195
+ if (!isRecord(value)) {
6196
+ return {
6197
+ issues: [
6198
+ {
6199
+ message: "expected an object"
6200
+ }
6201
+ ]
6202
+ };
6203
+ }
6204
+ const issues = [];
6205
+ if (value.confirm != null && typeof value.confirm !== "boolean") {
6206
+ issues.push({
6207
+ message: "expected a boolean",
6208
+ path: [
6209
+ "confirm"
6210
+ ]
6211
+ });
6212
+ }
6213
+ if (value.confirmToken != null && typeof value.confirmToken !== "string") {
6214
+ issues.push({
6215
+ message: "expected a string",
6216
+ path: [
6217
+ "confirmToken"
6218
+ ]
6219
+ });
6220
+ }
6221
+ const { args, fields } = splitConfirm(value);
6222
+ const result = await inner.validate(args);
6223
+ if (result.issues !== void 0) {
6224
+ return {
6225
+ issues: [
6226
+ ...issues,
6227
+ ...result.issues
6228
+ ]
6229
+ };
6230
+ }
6231
+ if (issues.length > 0) {
6232
+ return {
6233
+ issues
6234
+ };
6235
+ }
6236
+ return {
6237
+ value: isRecord(result.value) ? {
6238
+ ...result.value,
6239
+ ...fields
6240
+ } : result.value
6241
+ };
6242
+ }, "validate"),
6243
+ jsonSchema: {
6244
+ input: describe,
6245
+ output: describe
6246
+ }
6247
+ }
6248
+ };
6249
+ return wrapped;
6250
+ }
6251
+ __name(withConfirmFields, "withConfirmFields");
6252
+ function defineConfirmedTool(options, steps) {
6253
+ const { secret, ttlMs = DEFAULT_CONFIRM_TTL_MS, store, messages, input, ...specFields } = options;
6254
+ const text = {
6255
+ ...DEFAULT_MESSAGES,
6256
+ ...messages
6257
+ };
6258
+ const howToConfirm = text.confirm.replaceAll("{minutes}", String(Math.round(ttlMs / 6e4)));
6259
+ const secretNow = /* @__PURE__ */ __name(() => typeof secret === "function" ? secret() : secret, "secretNow");
6260
+ const handler = {
6261
+ async execute(value, ctx) {
6262
+ const { args, fields } = splitConfirm(value);
6263
+ const subject = {
6264
+ tool: options.name,
6265
+ actorId: ctx.actor.id,
6266
+ ...ctx.actor.tenantRef !== void 0 ? {
6267
+ tenantRef: ctx.actor.tenantRef
6268
+ } : {},
6269
+ args
6270
+ };
6271
+ const confirming = fields.confirm === true;
6272
+ const token = fields.confirmToken;
6273
+ if (confirming && !verifyConfirmToken(token, subject, {
6274
+ secret: secretNow()
6275
+ })) {
6276
+ throw new ConfirmTokenError("invalid", text.invalid);
6277
+ }
6278
+ const prepared = await steps.prepare(args, ctx);
6279
+ if (!confirming || token === void 0) {
6280
+ const preview = await steps.preview(prepared, ctx);
6281
+ const expiresAt = Date.now() + ttlMs;
6282
+ return {
6283
+ status: "preview",
6284
+ summary: preview.summary,
6285
+ ...preview.data !== void 0 ? {
6286
+ data: preview.data
6287
+ } : {},
6288
+ confirmToken: signConfirmToken(subject, {
6289
+ secret: secretNow(),
6290
+ expiresAt
6291
+ }),
6292
+ expiresAt: new Date(expiresAt).toISOString(),
6293
+ confirm: howToConfirm
6294
+ };
6295
+ }
6296
+ const hash = hashConfirmToken(token);
6297
+ if (store !== void 0) {
6298
+ const claimed = await store.claim({
6299
+ hash,
6300
+ actorRef: ctx.actor.id,
6301
+ tool: options.name,
6302
+ expiresAt: confirmTokenExpiry(token) ?? Date.now() + ttlMs
6303
+ });
6304
+ if (!claimed) {
6305
+ throw new ConfirmTokenError("used", text.used);
6306
+ }
6307
+ }
6308
+ try {
6309
+ const done = await steps.commit(prepared, ctx);
6310
+ return {
6311
+ status: "done",
6312
+ summary: done.summary,
6313
+ ...done.data !== void 0 ? {
6314
+ data: done.data
6315
+ } : {}
6316
+ };
6317
+ } catch (error) {
6318
+ await store?.release(hash).catch(() => void 0);
6319
+ throw error;
6320
+ }
6321
+ }
6322
+ };
6323
+ return {
6324
+ spec: {
6325
+ ...specFields,
6326
+ kind: "read",
6327
+ inputSchema: withConfirmFields(input)
6328
+ },
6329
+ handler
6330
+ };
6331
+ }
6332
+ __name(defineConfirmedTool, "defineConfirmedTool");
6009
6333
  // Annotate the CommonJS export names for ESM import in node:
6010
6334
  0 && (module.exports = {
6011
6335
  AGENT_ACTOR_DIRECTORY,
6012
6336
  AGENT_ACTOR_RESOLVER,
6013
6337
  AGENT_APPROVAL_PORT,
6014
6338
  AGENT_ATTACHMENT_STAGING,
6339
+ AGENT_CONFIRM_TOKEN_STORE,
6015
6340
  AGENT_DEPS_FACTORY,
6016
6341
  AGENT_DIAGNOSTIC_EVENTS,
6017
6342
  AGENT_DURABLE_RUNNER,
@@ -6041,7 +6366,10 @@ var InMemoryAgentStore = class {
6041
6366
  ASK_TOOL_NAME,
6042
6367
  AgentRegistry,
6043
6368
  AgentStreamError,
6369
+ CONFIRM_JSON_SCHEMA_PROPERTIES,
6044
6370
  ClosedRolesPolicy,
6371
+ ConfirmTokenError,
6372
+ DEFAULT_CONFIRM_TTL_MS,
6045
6373
  DEFAULT_HISTORY_SUMMARY_INSTRUCTION,
6046
6374
  DEFAULT_INCREMENTAL_LOOKBACK_CHARS,
6047
6375
  DEFAULT_INTAKE_PREAMBLE,
@@ -6057,6 +6385,7 @@ var InMemoryAgentStore = class {
6057
6385
  ELICITATION_INPUT_TYPES,
6058
6386
  GLOBAL_SCOPE,
6059
6387
  InMemoryAgentStore,
6388
+ InMemoryConfirmTokenStore,
6060
6389
  MAX_ASK_QUESTIONS,
6061
6390
  OutputRejectedError,
6062
6391
  ProcessorFailedError,
@@ -6070,6 +6399,7 @@ var InMemoryAgentStore = class {
6070
6399
  RUN_NOT_ACTIVE_MESSAGE,
6071
6400
  RUN_NO_LONGER_RUNNING,
6072
6401
  RunCancelledError,
6402
+ SCHEMA_EXTENSION,
6073
6403
  SKILL_TOOL_DESCRIPTION,
6074
6404
  SKILL_TOOL_NAME,
6075
6405
  StructuredOutputError,
@@ -6092,8 +6422,10 @@ var InMemoryAgentStore = class {
6092
6422
  buildMemoryBlock,
6093
6423
  buildSkillsBlock,
6094
6424
  canActorUseTool,
6425
+ canonicalJson,
6095
6426
  closeEmptyRoles,
6096
6427
  compositeSkillProvider,
6428
+ confirmTokenExpiry,
6097
6429
  createFrameBuffer,
6098
6430
  createIncrementalGate,
6099
6431
  createNoopEmitUi,
@@ -6103,6 +6435,7 @@ var InMemoryAgentStore = class {
6103
6435
  decodeStreamEvent,
6104
6436
  defaultCanDecide,
6105
6437
  defaultScopeResolver,
6438
+ defineConfirmedTool,
6106
6439
  detachedDelivered,
6107
6440
  detachedStarted,
6108
6441
  detachedUnsettled,
@@ -6119,6 +6452,7 @@ var InMemoryAgentStore = class {
6119
6452
  findCatalogModel,
6120
6453
  gateFollowUps,
6121
6454
  gateTail,
6455
+ hashConfirmToken,
6122
6456
  invokeWithTransientRetry,
6123
6457
  isChatQueueStore,
6124
6458
  isControlFlowSignal,
@@ -6171,12 +6505,14 @@ var InMemoryAgentStore = class {
6171
6505
  runAgentLoop,
6172
6506
  runInputProcessors,
6173
6507
  runOutputProcessors,
6508
+ schemaExtensionOf,
6174
6509
  seedModelPrices,
6175
6510
  settleAll,
6176
6511
  settleDanglingToolCalls,
6177
6512
  settleDeadRun,
6178
6513
  settleElicitation,
6179
6514
  settleUnsettledDelegation,
6515
+ signConfirmToken,
6180
6516
  skillInputSchema,
6181
6517
  skillToolDefinition,
6182
6518
  skillWriteVerdict,
@@ -6195,8 +6531,10 @@ var InMemoryAgentStore = class {
6195
6531
  validateElicitationAnswer,
6196
6532
  validateElicitationValue,
6197
6533
  validateStructured,
6534
+ verifyConfirmToken,
6198
6535
  windowHistory,
6199
6536
  withAskTool,
6537
+ withConfirmFields,
6200
6538
  withMemoryTool,
6201
6539
  withSelectedModel,
6202
6540
  withSkillTool,