@dudousxd/nestjs-agent-core 0.19.0 → 0.21.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/README.md +3 -1
- package/dist/guardrails/index.d.cts +1 -1
- package/dist/guardrails/index.d.ts +1 -1
- package/dist/index.cjs +622 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +151 -5
- package/dist/index.d.ts +151 -5
- package/dist/index.js +609 -42
- package/dist/index.js.map +1 -1
- package/dist/{tool-Q2rmGeaG.d.cts → tool-CwXibnce.d.cts} +164 -3
- package/dist/{tool-Q2rmGeaG.d.ts → tool-CwXibnce.d.ts} +164 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -46,6 +46,7 @@ __export(src_exports, {
|
|
|
46
46
|
AGENT_SPAN_EVENTS: () => AGENT_SPAN_EVENTS,
|
|
47
47
|
AGENT_STORE: () => AGENT_STORE,
|
|
48
48
|
AGENT_TOOL_REGISTRY: () => AGENT_TOOL_REGISTRY,
|
|
49
|
+
APPROVAL_EXPIRED_REASON: () => APPROVAL_EXPIRED_REASON,
|
|
49
50
|
ASK_TOOL_DESCRIPTION: () => ASK_TOOL_DESCRIPTION,
|
|
50
51
|
ASK_TOOL_NAME: () => ASK_TOOL_NAME,
|
|
51
52
|
AgentRegistry: () => AgentRegistry,
|
|
@@ -60,7 +61,9 @@ __export(src_exports, {
|
|
|
60
61
|
DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION: () => DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION,
|
|
61
62
|
DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS: () => DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS,
|
|
62
63
|
DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS: () => DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS,
|
|
64
|
+
DefaultApprovalPolicy: () => DefaultApprovalPolicy,
|
|
63
65
|
DefaultRolesPolicy: () => DefaultRolesPolicy,
|
|
66
|
+
ELICITATION_INPUT_TYPES: () => ELICITATION_INPUT_TYPES,
|
|
64
67
|
GLOBAL_SCOPE: () => GLOBAL_SCOPE,
|
|
65
68
|
MAX_ASK_QUESTIONS: () => MAX_ASK_QUESTIONS,
|
|
66
69
|
OutputRejectedError: () => OutputRejectedError,
|
|
@@ -68,6 +71,7 @@ __export(src_exports, {
|
|
|
68
71
|
QuotaExceededError: () => QuotaExceededError,
|
|
69
72
|
REMEMBER_TOOL_DESCRIPTION: () => REMEMBER_TOOL_DESCRIPTION,
|
|
70
73
|
REMEMBER_TOOL_NAME: () => REMEMBER_TOOL_NAME,
|
|
74
|
+
REQUESTER_APPROVER: () => REQUESTER_APPROVER,
|
|
71
75
|
RunCancelledError: () => RunCancelledError,
|
|
72
76
|
SKILL_TOOL_DESCRIPTION: () => SKILL_TOOL_DESCRIPTION,
|
|
73
77
|
SKILL_TOOL_NAME: () => SKILL_TOOL_NAME,
|
|
@@ -95,6 +99,7 @@ __export(src_exports, {
|
|
|
95
99
|
createIncrementalGate: () => createIncrementalGate,
|
|
96
100
|
dayBoundsUtc: () => dayBoundsUtc,
|
|
97
101
|
decodeStreamEvent: () => decodeStreamEvent,
|
|
102
|
+
defaultCanDecide: () => defaultCanDecide,
|
|
98
103
|
defaultScopeResolver: () => defaultScopeResolver,
|
|
99
104
|
detachedDelivered: () => detachedDelivered,
|
|
100
105
|
detachedStarted: () => detachedStarted,
|
|
@@ -114,7 +119,9 @@ __export(src_exports, {
|
|
|
114
119
|
isReplayIntegrityError: () => isReplayIntegrityError,
|
|
115
120
|
isToolEnabled: () => isToolEnabled,
|
|
116
121
|
isTransientToolError: () => isTransientToolError,
|
|
122
|
+
isTypedQuestion: () => isTypedQuestion,
|
|
117
123
|
loadSkill: () => loadSkill,
|
|
124
|
+
mayDecideApproval: () => mayDecideApproval,
|
|
118
125
|
memoryForgetVerdict: () => memoryForgetVerdict,
|
|
119
126
|
memoryWriteVerdict: () => memoryWriteVerdict,
|
|
120
127
|
normalizeDelegation: () => normalizeDelegation,
|
|
@@ -134,6 +141,9 @@ __export(src_exports, {
|
|
|
134
141
|
publishAgentSkillsResolved: () => publishAgentSkillsResolved,
|
|
135
142
|
publishAgentToolCall: () => publishAgentToolCall,
|
|
136
143
|
publishAgentToolRetry: () => publishAgentToolRetry,
|
|
144
|
+
questionOptions: () => questionOptions,
|
|
145
|
+
readElicitationInput: () => readElicitationInput,
|
|
146
|
+
readElicitationQuestions: () => readElicitationQuestions,
|
|
137
147
|
releaseGatedFrames: () => releaseGatedFrames,
|
|
138
148
|
rememberInputSchema: () => rememberInputSchema,
|
|
139
149
|
rememberToolDefinition: () => rememberToolDefinition,
|
|
@@ -160,9 +170,12 @@ __export(src_exports, {
|
|
|
160
170
|
staticSkillProvider: () => staticSkillProvider,
|
|
161
171
|
summarizeWithModel: () => summarizeWithModel,
|
|
162
172
|
tenantScope: () => tenantScope,
|
|
173
|
+
toolCallApprovalFromRow: () => toolCallApprovalFromRow,
|
|
163
174
|
traceLlmTurn: () => traceLlmTurn,
|
|
164
175
|
traceToolExecution: () => traceToolExecution,
|
|
165
176
|
truncateDetailContent: () => truncateDetailContent,
|
|
177
|
+
validateElicitationAnswer: () => validateElicitationAnswer,
|
|
178
|
+
validateElicitationValue: () => validateElicitationValue,
|
|
166
179
|
validateStructured: () => validateStructured,
|
|
167
180
|
windowHistory: () => windowHistory,
|
|
168
181
|
withAskTool: () => withAskTool,
|
|
@@ -388,6 +401,63 @@ function truncateDetailContent(content) {
|
|
|
388
401
|
}
|
|
389
402
|
__name(truncateDetailContent, "truncateDetailContent");
|
|
390
403
|
|
|
404
|
+
// src/spi/approval-policy.ts
|
|
405
|
+
var REQUESTER_APPROVER = "requester";
|
|
406
|
+
var DefaultApprovalPolicy = class {
|
|
407
|
+
static {
|
|
408
|
+
__name(this, "DefaultApprovalPolicy");
|
|
409
|
+
}
|
|
410
|
+
requirementFor(tool) {
|
|
411
|
+
return {
|
|
412
|
+
required: tool.kind === "action",
|
|
413
|
+
approver: REQUESTER_APPROVER
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
function defaultCanDecide(actor, decision) {
|
|
418
|
+
if (decision.approver === REQUESTER_APPROVER) {
|
|
419
|
+
return actor.id === decision.requesterRef;
|
|
420
|
+
}
|
|
421
|
+
return actor.roles?.includes(decision.approver) === true;
|
|
422
|
+
}
|
|
423
|
+
__name(defaultCanDecide, "defaultCanDecide");
|
|
424
|
+
async function mayDecideApproval(policy, actor, decision) {
|
|
425
|
+
if (policy?.canDecide !== void 0) {
|
|
426
|
+
return policy.canDecide(actor, decision);
|
|
427
|
+
}
|
|
428
|
+
return defaultCanDecide(actor, decision);
|
|
429
|
+
}
|
|
430
|
+
__name(mayDecideApproval, "mayDecideApproval");
|
|
431
|
+
function toolCallApprovalFromRow(row) {
|
|
432
|
+
if (row.approver === null || row.approver === void 0) {
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
const status = row.status === "pending_approval" ? "pending" : row.status === "rejected" ? "rejected" : row.status === "expired" ? "expired" : "approved";
|
|
436
|
+
const expiresAt = row.expiresAt instanceof Date ? row.expiresAt.toISOString() : typeof row.expiresAt === "string" ? row.expiresAt : void 0;
|
|
437
|
+
const decided = status === "approved" || status === "rejected";
|
|
438
|
+
return {
|
|
439
|
+
toolCallId: row.toolCallId,
|
|
440
|
+
approver: row.approver,
|
|
441
|
+
status,
|
|
442
|
+
...expiresAt !== void 0 ? {
|
|
443
|
+
expiresAt
|
|
444
|
+
} : {},
|
|
445
|
+
...row.remember === true ? {
|
|
446
|
+
remember: true
|
|
447
|
+
} : {},
|
|
448
|
+
...decided && typeof row.executedByRef === "string" ? {
|
|
449
|
+
decidedBy: row.executedByRef
|
|
450
|
+
} : {},
|
|
451
|
+
...decided && typeof row.decidedVia === "string" ? {
|
|
452
|
+
decidedVia: row.decidedVia
|
|
453
|
+
} : {},
|
|
454
|
+
...status === "rejected" && typeof row.error === "string" ? {
|
|
455
|
+
reason: row.error
|
|
456
|
+
} : {}
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
__name(toolCallApprovalFromRow, "toolCallApprovalFromRow");
|
|
460
|
+
|
|
391
461
|
// src/governance/compute.ts
|
|
392
462
|
function estimateCost(usage, price) {
|
|
393
463
|
if (price === void 0) {
|
|
@@ -947,11 +1017,235 @@ ${detail}`;
|
|
|
947
1017
|
}
|
|
948
1018
|
__name(repairInstruction, "repairInstruction");
|
|
949
1019
|
|
|
950
|
-
// src/elicitation.ts
|
|
951
|
-
|
|
952
|
-
|
|
1020
|
+
// src/elicitation-input.ts
|
|
1021
|
+
var ELICITATION_INPUT_TYPES = [
|
|
1022
|
+
"text",
|
|
1023
|
+
"textarea",
|
|
1024
|
+
"number",
|
|
1025
|
+
"boolean",
|
|
1026
|
+
"date",
|
|
1027
|
+
"email",
|
|
1028
|
+
"url",
|
|
1029
|
+
"select"
|
|
1030
|
+
];
|
|
1031
|
+
function questionOptions(question) {
|
|
1032
|
+
return question.options ?? [];
|
|
1033
|
+
}
|
|
1034
|
+
__name(questionOptions, "questionOptions");
|
|
1035
|
+
function isTypedQuestion(question) {
|
|
1036
|
+
return question.input !== void 0 && question.input.type !== "select";
|
|
1037
|
+
}
|
|
1038
|
+
__name(isTypedQuestion, "isTypedQuestion");
|
|
1039
|
+
var DATE_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
1040
|
+
var EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1041
|
+
var NUMBER_PATTERN = /^-?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i;
|
|
1042
|
+
function isDate(value) {
|
|
1043
|
+
const match = DATE_PATTERN.exec(value);
|
|
1044
|
+
if (match === null) {
|
|
1045
|
+
return false;
|
|
1046
|
+
}
|
|
1047
|
+
const [, year, month, day] = match;
|
|
1048
|
+
const date = new Date(Date.UTC(Number(year), Number(month) - 1, Number(day)));
|
|
1049
|
+
return date.getUTCFullYear() === Number(year) && date.getUTCMonth() === Number(month) - 1 && date.getUTCDate() === Number(day);
|
|
1050
|
+
}
|
|
1051
|
+
__name(isDate, "isDate");
|
|
1052
|
+
function isHttpUrl(value) {
|
|
1053
|
+
try {
|
|
1054
|
+
const url = new URL(value);
|
|
1055
|
+
return url.protocol === "http:" || url.protocol === "https:";
|
|
1056
|
+
} catch {
|
|
1057
|
+
return false;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
__name(isHttpUrl, "isHttpUrl");
|
|
1061
|
+
function fullMatch(pattern, value) {
|
|
1062
|
+
try {
|
|
1063
|
+
return new RegExp(`^(?:${pattern})$`, "u").test(value);
|
|
1064
|
+
} catch {
|
|
1065
|
+
return void 0;
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
__name(fullMatch, "fullMatch");
|
|
1069
|
+
function asNumber(bound) {
|
|
1070
|
+
if (typeof bound === "number" && Number.isFinite(bound)) {
|
|
1071
|
+
return bound;
|
|
1072
|
+
}
|
|
1073
|
+
if (typeof bound === "string" && NUMBER_PATTERN.test(bound.trim())) {
|
|
1074
|
+
return Number(bound);
|
|
1075
|
+
}
|
|
1076
|
+
return void 0;
|
|
1077
|
+
}
|
|
1078
|
+
__name(asNumber, "asNumber");
|
|
1079
|
+
function validateElicitationValue(question, value) {
|
|
1080
|
+
const input = question.input;
|
|
1081
|
+
if (input === void 0 || input.type === "select") {
|
|
1082
|
+
if (question.allowFreeText === true) {
|
|
1083
|
+
return null;
|
|
1084
|
+
}
|
|
1085
|
+
return questionOptions(question).some((option) => option.value === value) ? null : "must be one of the offered options";
|
|
1086
|
+
}
|
|
1087
|
+
switch (input.type) {
|
|
1088
|
+
case "number": {
|
|
1089
|
+
if (!NUMBER_PATTERN.test(value.trim()) || !Number.isFinite(Number(value))) {
|
|
1090
|
+
return "must be a number";
|
|
1091
|
+
}
|
|
1092
|
+
const number = Number(value);
|
|
1093
|
+
const min = asNumber(input.min);
|
|
1094
|
+
const max = asNumber(input.max);
|
|
1095
|
+
if (min !== void 0 && number < min) {
|
|
1096
|
+
return `must be at least ${min}`;
|
|
1097
|
+
}
|
|
1098
|
+
if (max !== void 0 && number > max) {
|
|
1099
|
+
return `must be at most ${max}`;
|
|
1100
|
+
}
|
|
1101
|
+
return null;
|
|
1102
|
+
}
|
|
1103
|
+
case "boolean":
|
|
1104
|
+
return value === "true" || value === "false" ? null : 'must be "true" or "false"';
|
|
1105
|
+
case "date": {
|
|
1106
|
+
if (!isDate(value)) {
|
|
1107
|
+
return "must be a date as YYYY-MM-DD";
|
|
1108
|
+
}
|
|
1109
|
+
if (typeof input.min === "string" && isDate(input.min) && value < input.min) {
|
|
1110
|
+
return `must be on or after ${input.min}`;
|
|
1111
|
+
}
|
|
1112
|
+
if (typeof input.max === "string" && isDate(input.max) && value > input.max) {
|
|
1113
|
+
return `must be on or before ${input.max}`;
|
|
1114
|
+
}
|
|
1115
|
+
return null;
|
|
1116
|
+
}
|
|
1117
|
+
case "email":
|
|
1118
|
+
if (!EMAIL_PATTERN.test(value)) {
|
|
1119
|
+
return "must be an email address";
|
|
1120
|
+
}
|
|
1121
|
+
break;
|
|
1122
|
+
case "url":
|
|
1123
|
+
if (!isHttpUrl(value)) {
|
|
1124
|
+
return "must be an http(s) URL";
|
|
1125
|
+
}
|
|
1126
|
+
break;
|
|
1127
|
+
case "text":
|
|
1128
|
+
case "textarea": {
|
|
1129
|
+
const min = asNumber(input.min);
|
|
1130
|
+
const max = asNumber(input.max);
|
|
1131
|
+
if (min !== void 0 && value.length < min) {
|
|
1132
|
+
return `must be at least ${min} characters`;
|
|
1133
|
+
}
|
|
1134
|
+
if (max !== void 0 && value.length > max) {
|
|
1135
|
+
return `must be at most ${max} characters`;
|
|
1136
|
+
}
|
|
1137
|
+
break;
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
if (input.pattern !== void 0 && fullMatch(input.pattern, value) === false) {
|
|
1141
|
+
return "does not match the expected format";
|
|
1142
|
+
}
|
|
1143
|
+
return null;
|
|
1144
|
+
}
|
|
1145
|
+
__name(validateElicitationValue, "validateElicitationValue");
|
|
1146
|
+
function validateElicitationAnswer(question, values) {
|
|
1147
|
+
const present = values.filter((value) => value !== "");
|
|
1148
|
+
if (present.length === 0) {
|
|
1149
|
+
return question.input?.required === true ? "requires an answer" : null;
|
|
1150
|
+
}
|
|
1151
|
+
if (question.multiple !== true && present.length > 1) {
|
|
1152
|
+
return "takes a single value";
|
|
1153
|
+
}
|
|
1154
|
+
for (const value of present) {
|
|
1155
|
+
const problem = validateElicitationValue(question, value);
|
|
1156
|
+
if (problem !== null) {
|
|
1157
|
+
return problem;
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
return null;
|
|
1161
|
+
}
|
|
1162
|
+
__name(validateElicitationAnswer, "validateElicitationAnswer");
|
|
1163
|
+
function readElicitationInput(raw) {
|
|
1164
|
+
if (typeof raw !== "object" || raw === null) {
|
|
1165
|
+
return void 0;
|
|
1166
|
+
}
|
|
1167
|
+
const candidate = raw;
|
|
1168
|
+
const type = candidate.type;
|
|
1169
|
+
if (typeof type !== "string" || !ELICITATION_INPUT_TYPES.includes(type)) {
|
|
1170
|
+
return void 0;
|
|
1171
|
+
}
|
|
1172
|
+
const bound = /* @__PURE__ */ __name((value) => typeof value === "number" && Number.isFinite(value) || typeof value === "string" ? value : void 0, "bound");
|
|
1173
|
+
const min = bound(candidate.min);
|
|
1174
|
+
const max = bound(candidate.max);
|
|
1175
|
+
return {
|
|
1176
|
+
type,
|
|
1177
|
+
...typeof candidate.placeholder === "string" ? {
|
|
1178
|
+
placeholder: candidate.placeholder
|
|
1179
|
+
} : {},
|
|
1180
|
+
...candidate.required === true ? {
|
|
1181
|
+
required: true
|
|
1182
|
+
} : {},
|
|
1183
|
+
...min !== void 0 ? {
|
|
1184
|
+
min
|
|
1185
|
+
} : {},
|
|
1186
|
+
...max !== void 0 ? {
|
|
1187
|
+
max
|
|
1188
|
+
} : {},
|
|
1189
|
+
...typeof candidate.pattern === "string" ? {
|
|
1190
|
+
pattern: candidate.pattern
|
|
1191
|
+
} : {}
|
|
1192
|
+
};
|
|
953
1193
|
}
|
|
954
|
-
__name(
|
|
1194
|
+
__name(readElicitationInput, "readElicitationInput");
|
|
1195
|
+
function readElicitationQuestions(input) {
|
|
1196
|
+
if (typeof input !== "object" || input === null) {
|
|
1197
|
+
return [];
|
|
1198
|
+
}
|
|
1199
|
+
const raw = input.questions;
|
|
1200
|
+
if (!Array.isArray(raw)) {
|
|
1201
|
+
return [];
|
|
1202
|
+
}
|
|
1203
|
+
const questions = [];
|
|
1204
|
+
for (const item of raw) {
|
|
1205
|
+
if (typeof item !== "object" || item === null) {
|
|
1206
|
+
continue;
|
|
1207
|
+
}
|
|
1208
|
+
const candidate = item;
|
|
1209
|
+
if (typeof candidate.id !== "string" || typeof candidate.prompt !== "string") {
|
|
1210
|
+
continue;
|
|
1211
|
+
}
|
|
1212
|
+
const options = Array.isArray(candidate.options) ? candidate.options.flatMap((option) => {
|
|
1213
|
+
if (typeof option !== "object" || option === null) {
|
|
1214
|
+
return [];
|
|
1215
|
+
}
|
|
1216
|
+
const { value, label } = option;
|
|
1217
|
+
return typeof value === "string" && typeof label === "string" ? [
|
|
1218
|
+
{
|
|
1219
|
+
value,
|
|
1220
|
+
label
|
|
1221
|
+
}
|
|
1222
|
+
] : [];
|
|
1223
|
+
}) : [];
|
|
1224
|
+
const typed = readElicitationInput(candidate.input);
|
|
1225
|
+
const defaults = Array.isArray(candidate.defaults) ? candidate.defaults.filter((value) => typeof value === "string") : [];
|
|
1226
|
+
questions.push({
|
|
1227
|
+
id: candidate.id,
|
|
1228
|
+
prompt: candidate.prompt,
|
|
1229
|
+
options,
|
|
1230
|
+
...typed !== void 0 ? {
|
|
1231
|
+
input: typed
|
|
1232
|
+
} : {},
|
|
1233
|
+
...defaults.length > 0 ? {
|
|
1234
|
+
defaults
|
|
1235
|
+
} : {},
|
|
1236
|
+
...candidate.multiple === true ? {
|
|
1237
|
+
multiple: true
|
|
1238
|
+
} : {},
|
|
1239
|
+
...candidate.allowFreeText === true ? {
|
|
1240
|
+
allowFreeText: true
|
|
1241
|
+
} : {}
|
|
1242
|
+
});
|
|
1243
|
+
}
|
|
1244
|
+
return questions;
|
|
1245
|
+
}
|
|
1246
|
+
__name(readElicitationQuestions, "readElicitationQuestions");
|
|
1247
|
+
|
|
1248
|
+
// src/elicitation.ts
|
|
955
1249
|
function normalizeElicitationReply(reply) {
|
|
956
1250
|
if (typeof reply !== "object" || reply === null) {
|
|
957
1251
|
return {
|
|
@@ -987,8 +1281,7 @@ function resolveElicitation(request, raw) {
|
|
|
987
1281
|
defaulted.push(question.id);
|
|
988
1282
|
continue;
|
|
989
1283
|
}
|
|
990
|
-
const
|
|
991
|
-
const valid = question.allowFreeText === true ? submitted : submitted.filter((value) => allowed.has(value));
|
|
1284
|
+
const valid = submitted.filter((value) => value !== "" && validateElicitationValue(question, value) === null);
|
|
992
1285
|
answers[question.id] = question.multiple === true ? valid : valid.slice(0, 1);
|
|
993
1286
|
}
|
|
994
1287
|
return {
|
|
@@ -1009,7 +1302,7 @@ __name(settleElicitation, "settleElicitation");
|
|
|
1009
1302
|
function renderElicitationAnswers(request, outcome) {
|
|
1010
1303
|
const lines = request.questions.map((question) => {
|
|
1011
1304
|
const chosen = outcome.answers[question.id] ?? [];
|
|
1012
|
-
const labels = chosen.map((value) => question.
|
|
1305
|
+
const labels = chosen.map((value) => questionOptions(question).find((option) => option.value === value)?.label ?? value);
|
|
1013
1306
|
return `${question.prompt} \u2192 ${labels.length > 0 ? labels.join(", ") : "(no answer)"}`;
|
|
1014
1307
|
});
|
|
1015
1308
|
const preface = outcome.skipped ? "The user declined to answer and asked you to proceed on these assumptions:" : "The user answered:";
|
|
@@ -1075,7 +1368,23 @@ function parseQuestion(raw, path, issues) {
|
|
|
1075
1368
|
], "must be a non-empty string"));
|
|
1076
1369
|
return void 0;
|
|
1077
1370
|
}
|
|
1078
|
-
|
|
1371
|
+
let input;
|
|
1372
|
+
if (candidate.input !== void 0) {
|
|
1373
|
+
input = readElicitationInput(candidate.input);
|
|
1374
|
+
if (input === void 0) {
|
|
1375
|
+
issues.push(issue([
|
|
1376
|
+
...path,
|
|
1377
|
+
"input",
|
|
1378
|
+
"type"
|
|
1379
|
+
], `must be one of ${ELICITATION_INPUT_TYPES.join(", ")}`));
|
|
1380
|
+
return void 0;
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
const described = typeof candidate.description === "string" && candidate.description.length > 0 ? {
|
|
1384
|
+
description: candidate.description
|
|
1385
|
+
} : {};
|
|
1386
|
+
const typed = input !== void 0 && input.type !== "select";
|
|
1387
|
+
if (!typed && (!Array.isArray(candidate.options) || candidate.options.length === 0)) {
|
|
1079
1388
|
issues.push(issue([
|
|
1080
1389
|
...path,
|
|
1081
1390
|
"options"
|
|
@@ -1083,7 +1392,7 @@ function parseQuestion(raw, path, issues) {
|
|
|
1083
1392
|
return void 0;
|
|
1084
1393
|
}
|
|
1085
1394
|
const options = [];
|
|
1086
|
-
for (const [index, rawOption] of candidate.options.entries()) {
|
|
1395
|
+
for (const [index, rawOption] of (Array.isArray(candidate.options) ? candidate.options : []).entries()) {
|
|
1087
1396
|
const option = parseOption(rawOption, [
|
|
1088
1397
|
...path,
|
|
1089
1398
|
"options",
|
|
@@ -1093,6 +1402,33 @@ function parseQuestion(raw, path, issues) {
|
|
|
1093
1402
|
options.push(option);
|
|
1094
1403
|
}
|
|
1095
1404
|
}
|
|
1405
|
+
if (typed) {
|
|
1406
|
+
const question = {
|
|
1407
|
+
id: candidate.id,
|
|
1408
|
+
prompt: candidate.prompt,
|
|
1409
|
+
...described,
|
|
1410
|
+
...options.length > 0 ? {
|
|
1411
|
+
options
|
|
1412
|
+
} : {},
|
|
1413
|
+
input,
|
|
1414
|
+
...candidate.multiple === true ? {
|
|
1415
|
+
multiple: true
|
|
1416
|
+
} : {}
|
|
1417
|
+
};
|
|
1418
|
+
const offered2 = Array.isArray(candidate.defaults) ? candidate.defaults.filter((value) => typeof value === "string") : [];
|
|
1419
|
+
const defaults2 = offered2.filter((value) => validateElicitationValue(question, value) === null);
|
|
1420
|
+
if (offered2.length > 0 && defaults2.length === 0) {
|
|
1421
|
+
issues.push(issue([
|
|
1422
|
+
...path,
|
|
1423
|
+
"defaults"
|
|
1424
|
+
], `must be valid ${input.type} values`));
|
|
1425
|
+
return void 0;
|
|
1426
|
+
}
|
|
1427
|
+
return defaults2.length > 0 ? {
|
|
1428
|
+
...question,
|
|
1429
|
+
defaults: defaults2
|
|
1430
|
+
} : question;
|
|
1431
|
+
}
|
|
1096
1432
|
if (!Array.isArray(candidate.defaults) || candidate.defaults.length === 0) {
|
|
1097
1433
|
issues.push(issue([
|
|
1098
1434
|
...path,
|
|
@@ -1112,7 +1448,11 @@ function parseQuestion(raw, path, issues) {
|
|
|
1112
1448
|
return {
|
|
1113
1449
|
id: candidate.id,
|
|
1114
1450
|
prompt: candidate.prompt,
|
|
1451
|
+
...described,
|
|
1115
1452
|
options,
|
|
1453
|
+
...input !== void 0 ? {
|
|
1454
|
+
input
|
|
1455
|
+
} : {},
|
|
1116
1456
|
defaults,
|
|
1117
1457
|
...candidate.multiple === true ? {
|
|
1118
1458
|
multiple: true
|
|
@@ -1140,9 +1480,7 @@ var ASK_JSON_SCHEMA = {
|
|
|
1140
1480
|
additionalProperties: false,
|
|
1141
1481
|
required: [
|
|
1142
1482
|
"id",
|
|
1143
|
-
"prompt"
|
|
1144
|
-
"options",
|
|
1145
|
-
"defaults"
|
|
1483
|
+
"prompt"
|
|
1146
1484
|
],
|
|
1147
1485
|
properties: {
|
|
1148
1486
|
id: {
|
|
@@ -1152,6 +1490,50 @@ var ASK_JSON_SCHEMA = {
|
|
|
1152
1490
|
prompt: {
|
|
1153
1491
|
type: "string"
|
|
1154
1492
|
},
|
|
1493
|
+
description: {
|
|
1494
|
+
type: "string",
|
|
1495
|
+
description: "A line of help under the prompt."
|
|
1496
|
+
},
|
|
1497
|
+
input: {
|
|
1498
|
+
type: "object",
|
|
1499
|
+
additionalProperties: false,
|
|
1500
|
+
required: [
|
|
1501
|
+
"type"
|
|
1502
|
+
],
|
|
1503
|
+
description: 'Ask for a typed value instead of offering options. Omit for a pick from options. Answers come back as strings: numbers as decimals, booleans as "true"/"false", dates as YYYY-MM-DD.',
|
|
1504
|
+
properties: {
|
|
1505
|
+
type: {
|
|
1506
|
+
type: "string",
|
|
1507
|
+
enum: [
|
|
1508
|
+
...ELICITATION_INPUT_TYPES
|
|
1509
|
+
]
|
|
1510
|
+
},
|
|
1511
|
+
placeholder: {
|
|
1512
|
+
type: "string"
|
|
1513
|
+
},
|
|
1514
|
+
required: {
|
|
1515
|
+
type: "boolean"
|
|
1516
|
+
},
|
|
1517
|
+
min: {
|
|
1518
|
+
type: [
|
|
1519
|
+
"number",
|
|
1520
|
+
"string"
|
|
1521
|
+
],
|
|
1522
|
+
description: "number: minimum; text: minimum length; date: earliest YYYY-MM-DD."
|
|
1523
|
+
},
|
|
1524
|
+
max: {
|
|
1525
|
+
type: [
|
|
1526
|
+
"number",
|
|
1527
|
+
"string"
|
|
1528
|
+
],
|
|
1529
|
+
description: "number: maximum; text: maximum length; date: latest YYYY-MM-DD."
|
|
1530
|
+
},
|
|
1531
|
+
pattern: {
|
|
1532
|
+
type: "string",
|
|
1533
|
+
description: "A regex the whole value must match."
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
},
|
|
1155
1537
|
multiple: {
|
|
1156
1538
|
type: "boolean",
|
|
1157
1539
|
description: "Allow more than one option to be chosen."
|
|
@@ -1166,7 +1548,7 @@ var ASK_JSON_SCHEMA = {
|
|
|
1166
1548
|
items: {
|
|
1167
1549
|
type: "string"
|
|
1168
1550
|
},
|
|
1169
|
-
description: "REQUIRED
|
|
1551
|
+
description: "REQUIRED for a pick from options: the option values you would pick yourself, so the user can confirm rather than decide. For a typed input, the value you would enter, when there is a sensible one."
|
|
1170
1552
|
},
|
|
1171
1553
|
options: {
|
|
1172
1554
|
type: "array",
|
|
@@ -2938,15 +3320,33 @@ async function claimToolCall(turn, call) {
|
|
|
2938
3320
|
const spec = deps.registry.spec(call.name);
|
|
2939
3321
|
const kind = call.kind ?? declaredKind(deps, call.name);
|
|
2940
3322
|
const awaitsHuman = kind === "action" || kind === "ask";
|
|
3323
|
+
const approval = kind === "action" ? await claimApproval(turn, call, spec) : void 0;
|
|
3324
|
+
const parks = kind === "ask" || approval?.mode === "ask";
|
|
2941
3325
|
await deps.store.recordToolCall({
|
|
2942
3326
|
toolCallId: call.id,
|
|
2943
3327
|
messageId,
|
|
2944
3328
|
toolName: call.name,
|
|
2945
3329
|
toolType: awaitsHuman ? "action" : "read",
|
|
2946
3330
|
input: call.input,
|
|
2947
|
-
status:
|
|
2948
|
-
runId: hooks.runId
|
|
3331
|
+
status: parks ? "pending_approval" : "auto_executed",
|
|
3332
|
+
runId: hooks.runId,
|
|
3333
|
+
...approval !== void 0 && approval.mode !== "auto" ? {
|
|
3334
|
+
approver: approval.approver
|
|
3335
|
+
} : {},
|
|
3336
|
+
...approval?.mode === "ask" && approval.expiresAt !== void 0 ? {
|
|
3337
|
+
expiresAt: approval.expiresAt
|
|
3338
|
+
} : {}
|
|
2949
3339
|
});
|
|
3340
|
+
if (approval?.mode === "ask") {
|
|
3341
|
+
await turn.writer.write(encodeStreamEvent({
|
|
3342
|
+
kind: "approval-requested",
|
|
3343
|
+
id: call.id,
|
|
3344
|
+
approver: approval.approver,
|
|
3345
|
+
...approval.expiresAt !== void 0 ? {
|
|
3346
|
+
expiresAt: approval.expiresAt
|
|
3347
|
+
} : {}
|
|
3348
|
+
}));
|
|
3349
|
+
}
|
|
2950
3350
|
return {
|
|
2951
3351
|
kind,
|
|
2952
3352
|
...spec?.targetAgent !== void 0 ? {
|
|
@@ -2956,6 +3356,9 @@ async function claimToolCall(turn, call) {
|
|
|
2956
3356
|
// deployment with no detached edge writes the same bytes here it always has.
|
|
2957
3357
|
...spec?.detached === true ? {
|
|
2958
3358
|
detached: true
|
|
3359
|
+
} : {},
|
|
3360
|
+
...approval !== void 0 ? {
|
|
3361
|
+
approval
|
|
2959
3362
|
} : {}
|
|
2960
3363
|
};
|
|
2961
3364
|
});
|
|
@@ -2975,10 +3378,52 @@ async function claimToolCall(turn, call) {
|
|
|
2975
3378
|
...persisted?.detached === true ? {
|
|
2976
3379
|
detached: true
|
|
2977
3380
|
} : {},
|
|
3381
|
+
...toolType === "action" && persisted?.approval !== void 0 ? {
|
|
3382
|
+
approval: persisted.approval
|
|
3383
|
+
} : {},
|
|
2978
3384
|
ctx: toolContext(deps, input, hooks)
|
|
2979
3385
|
};
|
|
2980
3386
|
}
|
|
2981
3387
|
__name(claimToolCall, "claimToolCall");
|
|
3388
|
+
async function claimApproval(turn, call, spec) {
|
|
3389
|
+
const { deps, input, hooks } = turn;
|
|
3390
|
+
const policy = deps.approvalPolicy ?? new DefaultApprovalPolicy();
|
|
3391
|
+
const requirement = await policy.requirementFor({
|
|
3392
|
+
name: call.name,
|
|
3393
|
+
kind: "action",
|
|
3394
|
+
...spec !== void 0 ? {
|
|
3395
|
+
spec
|
|
3396
|
+
} : {}
|
|
3397
|
+
}, input.actor, {
|
|
3398
|
+
threadId: input.threadId,
|
|
3399
|
+
runId: hooks.runId,
|
|
3400
|
+
...input.agentName !== void 0 ? {
|
|
3401
|
+
agentName: input.agentName
|
|
3402
|
+
} : {}
|
|
3403
|
+
});
|
|
3404
|
+
if (!requirement.required) {
|
|
3405
|
+
return {
|
|
3406
|
+
mode: "auto"
|
|
3407
|
+
};
|
|
3408
|
+
}
|
|
3409
|
+
const remembered = await deps.store.rememberedApprovals?.(input.threadId) ?? [];
|
|
3410
|
+
if (remembered.includes(call.name)) {
|
|
3411
|
+
return {
|
|
3412
|
+
mode: "remembered",
|
|
3413
|
+
approver: requirement.approver
|
|
3414
|
+
};
|
|
3415
|
+
}
|
|
3416
|
+
const ttlMs = requirement.ttlMs !== void 0 && Number.isFinite(requirement.ttlMs) && requirement.ttlMs > 0 ? Math.floor(requirement.ttlMs) : void 0;
|
|
3417
|
+
return {
|
|
3418
|
+
mode: "ask",
|
|
3419
|
+
approver: requirement.approver,
|
|
3420
|
+
...ttlMs !== void 0 ? {
|
|
3421
|
+
ttlMs,
|
|
3422
|
+
expiresAt: new Date(Date.now() + ttlMs).toISOString()
|
|
3423
|
+
} : {}
|
|
3424
|
+
};
|
|
3425
|
+
}
|
|
3426
|
+
__name(claimApproval, "claimApproval");
|
|
2982
3427
|
async function loadSkillIntoTurn(turn, claimed, startedAt) {
|
|
2983
3428
|
const { deps, input, hooks } = turn;
|
|
2984
3429
|
const { call } = claimed;
|
|
@@ -3162,17 +3607,50 @@ async function invokeClaimedTool(turn, claimed) {
|
|
|
3162
3607
|
}
|
|
3163
3608
|
}
|
|
3164
3609
|
__name(invokeClaimedTool, "invokeClaimedTool");
|
|
3165
|
-
async function recordToolOutcome(turn, claimed, outcome, deciderRef) {
|
|
3610
|
+
async function recordToolOutcome(turn, claimed, outcome, deciderRef, meta) {
|
|
3166
3611
|
const { deps, hooks } = turn;
|
|
3167
3612
|
const { call } = claimed;
|
|
3168
3613
|
const toolType = claimed.toolType === "action" ? "action" : "read";
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3614
|
+
const decided = meta === void 0 ? {} : {
|
|
3615
|
+
executedByRef: meta.decidedBy,
|
|
3616
|
+
...meta.decidedVia !== void 0 ? {
|
|
3617
|
+
decidedVia: meta.decidedVia
|
|
3618
|
+
} : {},
|
|
3619
|
+
...meta.remember === true ? {
|
|
3620
|
+
remember: true
|
|
3621
|
+
} : {}
|
|
3622
|
+
};
|
|
3623
|
+
const settle = /* @__PURE__ */ __name(async () => {
|
|
3624
|
+
if (meta === void 0 || !meta.streamed) {
|
|
3625
|
+
return;
|
|
3626
|
+
}
|
|
3627
|
+
await turn.writer.write(encodeStreamEvent({
|
|
3628
|
+
kind: "approval-settled",
|
|
3629
|
+
id: call.id,
|
|
3630
|
+
status: "approved",
|
|
3631
|
+
...meta.approver !== void 0 ? {
|
|
3632
|
+
approver: meta.approver
|
|
3633
|
+
} : {},
|
|
3634
|
+
decidedBy: meta.decidedBy,
|
|
3635
|
+
...meta.decidedVia !== void 0 ? {
|
|
3636
|
+
decidedVia: meta.decidedVia
|
|
3637
|
+
} : {},
|
|
3638
|
+
...meta.remember === true ? {
|
|
3639
|
+
remember: true
|
|
3640
|
+
} : {}
|
|
3175
3641
|
}));
|
|
3642
|
+
}, "settle");
|
|
3643
|
+
if (outcome.status === "failed") {
|
|
3644
|
+
await hooks.step(`persist:toolfail:${call.id}`, async () => {
|
|
3645
|
+
await deps.store.updateToolCall({
|
|
3646
|
+
toolCallId: call.id,
|
|
3647
|
+
status: "failed",
|
|
3648
|
+
error: outcome.error,
|
|
3649
|
+
executionMs: outcome.executionMs,
|
|
3650
|
+
...decided
|
|
3651
|
+
});
|
|
3652
|
+
await settle();
|
|
3653
|
+
});
|
|
3176
3654
|
publishAgentToolCall({
|
|
3177
3655
|
runId: hooks.runId,
|
|
3178
3656
|
toolName: call.name,
|
|
@@ -3187,15 +3665,19 @@ async function recordToolOutcome(turn, claimed, outcome, deciderRef) {
|
|
|
3187
3665
|
error: outcome.error
|
|
3188
3666
|
};
|
|
3189
3667
|
}
|
|
3190
|
-
await hooks.step(`persist:toolexec:${call.id}`, () =>
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3668
|
+
await hooks.step(`persist:toolexec:${call.id}`, async () => {
|
|
3669
|
+
await deps.store.updateToolCall({
|
|
3670
|
+
toolCallId: call.id,
|
|
3671
|
+
status: "executed",
|
|
3672
|
+
output: outcome.output,
|
|
3673
|
+
executionMs: outcome.executionMs,
|
|
3674
|
+
...toolType === "action" ? {
|
|
3675
|
+
executedByRef: deciderRef
|
|
3676
|
+
} : {},
|
|
3677
|
+
...decided
|
|
3678
|
+
});
|
|
3679
|
+
await settle();
|
|
3680
|
+
});
|
|
3199
3681
|
publishAgentToolCall({
|
|
3200
3682
|
runId: hooks.runId,
|
|
3201
3683
|
toolName: call.name,
|
|
@@ -3333,18 +3815,53 @@ async function runClaimedToolCall(turn, claimed) {
|
|
|
3333
3815
|
return elicitToolCall(turn, claimed);
|
|
3334
3816
|
}
|
|
3335
3817
|
let deciderRef = input.actor.id;
|
|
3336
|
-
|
|
3337
|
-
|
|
3818
|
+
let meta;
|
|
3819
|
+
if (toolType === "action" && claimed.approval?.mode === "remembered") {
|
|
3820
|
+
meta = {
|
|
3821
|
+
approver: claimed.approval.approver,
|
|
3822
|
+
decidedBy: input.actor.id,
|
|
3823
|
+
decidedVia: "remembered",
|
|
3824
|
+
remember: true,
|
|
3825
|
+
streamed: true
|
|
3826
|
+
};
|
|
3827
|
+
} else if (toolType === "action" && claimed.approval?.mode !== "auto") {
|
|
3828
|
+
const ttlMs = claimed.approval?.mode === "ask" ? claimed.approval.ttlMs : void 0;
|
|
3829
|
+
const decision = ttlMs !== void 0 ? await hooks.awaitApproval(call, ctx, {
|
|
3830
|
+
timeoutMs: ttlMs
|
|
3831
|
+
}) : await hooks.awaitApproval(call, ctx);
|
|
3338
3832
|
deciderRef = decision.executedByRef ?? input.actor.id;
|
|
3833
|
+
const streamsSettlement = claimed.approval !== void 0;
|
|
3834
|
+
if (decision.expired === true) {
|
|
3835
|
+
return expireToolCall(turn, claimed);
|
|
3836
|
+
}
|
|
3339
3837
|
if (!decision.approved) {
|
|
3340
|
-
await hooks.step(`persist:toolreject:${call.id}`, () =>
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3838
|
+
await hooks.step(`persist:toolreject:${call.id}`, async () => {
|
|
3839
|
+
await deps.store.updateToolCall({
|
|
3840
|
+
toolCallId: call.id,
|
|
3841
|
+
status: "rejected",
|
|
3842
|
+
executedByRef: deciderRef,
|
|
3843
|
+
...decision.reason !== void 0 ? {
|
|
3844
|
+
error: decision.reason
|
|
3845
|
+
} : {},
|
|
3846
|
+
...decision.decidedVia !== void 0 ? {
|
|
3847
|
+
decidedVia: decision.decidedVia
|
|
3848
|
+
} : {}
|
|
3849
|
+
});
|
|
3850
|
+
if (streamsSettlement) {
|
|
3851
|
+
await turn.writer.write(encodeStreamEvent({
|
|
3852
|
+
kind: "approval-settled",
|
|
3853
|
+
id: call.id,
|
|
3854
|
+
status: "rejected",
|
|
3855
|
+
decidedBy: deciderRef,
|
|
3856
|
+
...decision.decidedVia !== void 0 ? {
|
|
3857
|
+
decidedVia: decision.decidedVia
|
|
3858
|
+
} : {},
|
|
3859
|
+
...decision.reason !== void 0 ? {
|
|
3860
|
+
reason: decision.reason
|
|
3861
|
+
} : {}
|
|
3862
|
+
}));
|
|
3863
|
+
}
|
|
3864
|
+
});
|
|
3348
3865
|
publishAgentToolCall({
|
|
3349
3866
|
runId: hooks.runId,
|
|
3350
3867
|
toolName: call.name,
|
|
@@ -3367,10 +3884,60 @@ async function runClaimedToolCall(turn, claimed) {
|
|
|
3367
3884
|
error: refusalNarrative(decision.reason)
|
|
3368
3885
|
};
|
|
3369
3886
|
}
|
|
3887
|
+
meta = {
|
|
3888
|
+
decidedBy: deciderRef,
|
|
3889
|
+
...decision.decidedVia !== void 0 ? {
|
|
3890
|
+
decidedVia: decision.decidedVia
|
|
3891
|
+
} : {},
|
|
3892
|
+
...decision.remember === true ? {
|
|
3893
|
+
remember: true
|
|
3894
|
+
} : {},
|
|
3895
|
+
streamed: streamsSettlement
|
|
3896
|
+
};
|
|
3370
3897
|
}
|
|
3371
|
-
return recordToolOutcome(turn, claimed, await invokeClaimedTool(turn, claimed), deciderRef);
|
|
3898
|
+
return recordToolOutcome(turn, claimed, await invokeClaimedTool(turn, claimed), deciderRef, meta);
|
|
3372
3899
|
}
|
|
3373
3900
|
__name(runClaimedToolCall, "runClaimedToolCall");
|
|
3901
|
+
async function expireToolCall(turn, claimed) {
|
|
3902
|
+
const { deps, hooks } = turn;
|
|
3903
|
+
const { call } = claimed;
|
|
3904
|
+
await hooks.step(`persist:toolreject:${call.id}`, async () => {
|
|
3905
|
+
await deps.store.updateToolCall({
|
|
3906
|
+
toolCallId: call.id,
|
|
3907
|
+
status: "expired",
|
|
3908
|
+
error: APPROVAL_EXPIRED_REASON
|
|
3909
|
+
});
|
|
3910
|
+
await turn.writer.write(encodeStreamEvent({
|
|
3911
|
+
kind: "approval-settled",
|
|
3912
|
+
id: call.id,
|
|
3913
|
+
status: "expired"
|
|
3914
|
+
}));
|
|
3915
|
+
});
|
|
3916
|
+
publishAgentToolCall({
|
|
3917
|
+
runId: hooks.runId,
|
|
3918
|
+
toolName: call.name,
|
|
3919
|
+
toolType: "action",
|
|
3920
|
+
status: "rejected"
|
|
3921
|
+
});
|
|
3922
|
+
return {
|
|
3923
|
+
id: call.id,
|
|
3924
|
+
name: call.name,
|
|
3925
|
+
output: {
|
|
3926
|
+
rejected: true,
|
|
3927
|
+
expired: true,
|
|
3928
|
+
reason: APPROVAL_EXPIRED_REASON
|
|
3929
|
+
},
|
|
3930
|
+
denied: true,
|
|
3931
|
+
expired: true,
|
|
3932
|
+
error: expiryNarrative()
|
|
3933
|
+
};
|
|
3934
|
+
}
|
|
3935
|
+
__name(expireToolCall, "expireToolCall");
|
|
3936
|
+
var APPROVAL_EXPIRED_REASON = "approval expired";
|
|
3937
|
+
function expiryNarrative() {
|
|
3938
|
+
return "This action needed approval, and the approval request expired before anyone decided. Nothing ran and nothing changed. Do not run it again on your own; tell the person it was not approved in time and ask whether they still want it.";
|
|
3939
|
+
}
|
|
3940
|
+
__name(expiryNarrative, "expiryNarrative");
|
|
3374
3941
|
function outputFrame(result) {
|
|
3375
3942
|
if (result.denied === true) {
|
|
3376
3943
|
const reason = refusalReason(result);
|
|
@@ -4044,6 +4611,7 @@ __name(runAgentLoop, "runAgentLoop");
|
|
|
4044
4611
|
AGENT_SPAN_EVENTS,
|
|
4045
4612
|
AGENT_STORE,
|
|
4046
4613
|
AGENT_TOOL_REGISTRY,
|
|
4614
|
+
APPROVAL_EXPIRED_REASON,
|
|
4047
4615
|
ASK_TOOL_DESCRIPTION,
|
|
4048
4616
|
ASK_TOOL_NAME,
|
|
4049
4617
|
AgentRegistry,
|
|
@@ -4058,7 +4626,9 @@ __name(runAgentLoop, "runAgentLoop");
|
|
|
4058
4626
|
DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION,
|
|
4059
4627
|
DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS,
|
|
4060
4628
|
DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS,
|
|
4629
|
+
DefaultApprovalPolicy,
|
|
4061
4630
|
DefaultRolesPolicy,
|
|
4631
|
+
ELICITATION_INPUT_TYPES,
|
|
4062
4632
|
GLOBAL_SCOPE,
|
|
4063
4633
|
MAX_ASK_QUESTIONS,
|
|
4064
4634
|
OutputRejectedError,
|
|
@@ -4066,6 +4636,7 @@ __name(runAgentLoop, "runAgentLoop");
|
|
|
4066
4636
|
QuotaExceededError,
|
|
4067
4637
|
REMEMBER_TOOL_DESCRIPTION,
|
|
4068
4638
|
REMEMBER_TOOL_NAME,
|
|
4639
|
+
REQUESTER_APPROVER,
|
|
4069
4640
|
RunCancelledError,
|
|
4070
4641
|
SKILL_TOOL_DESCRIPTION,
|
|
4071
4642
|
SKILL_TOOL_NAME,
|
|
@@ -4093,6 +4664,7 @@ __name(runAgentLoop, "runAgentLoop");
|
|
|
4093
4664
|
createIncrementalGate,
|
|
4094
4665
|
dayBoundsUtc,
|
|
4095
4666
|
decodeStreamEvent,
|
|
4667
|
+
defaultCanDecide,
|
|
4096
4668
|
defaultScopeResolver,
|
|
4097
4669
|
detachedDelivered,
|
|
4098
4670
|
detachedStarted,
|
|
@@ -4112,7 +4684,9 @@ __name(runAgentLoop, "runAgentLoop");
|
|
|
4112
4684
|
isReplayIntegrityError,
|
|
4113
4685
|
isToolEnabled,
|
|
4114
4686
|
isTransientToolError,
|
|
4687
|
+
isTypedQuestion,
|
|
4115
4688
|
loadSkill,
|
|
4689
|
+
mayDecideApproval,
|
|
4116
4690
|
memoryForgetVerdict,
|
|
4117
4691
|
memoryWriteVerdict,
|
|
4118
4692
|
normalizeDelegation,
|
|
@@ -4132,6 +4706,9 @@ __name(runAgentLoop, "runAgentLoop");
|
|
|
4132
4706
|
publishAgentSkillsResolved,
|
|
4133
4707
|
publishAgentToolCall,
|
|
4134
4708
|
publishAgentToolRetry,
|
|
4709
|
+
questionOptions,
|
|
4710
|
+
readElicitationInput,
|
|
4711
|
+
readElicitationQuestions,
|
|
4135
4712
|
releaseGatedFrames,
|
|
4136
4713
|
rememberInputSchema,
|
|
4137
4714
|
rememberToolDefinition,
|
|
@@ -4158,9 +4735,12 @@ __name(runAgentLoop, "runAgentLoop");
|
|
|
4158
4735
|
staticSkillProvider,
|
|
4159
4736
|
summarizeWithModel,
|
|
4160
4737
|
tenantScope,
|
|
4738
|
+
toolCallApprovalFromRow,
|
|
4161
4739
|
traceLlmTurn,
|
|
4162
4740
|
traceToolExecution,
|
|
4163
4741
|
truncateDetailContent,
|
|
4742
|
+
validateElicitationAnswer,
|
|
4743
|
+
validateElicitationValue,
|
|
4164
4744
|
validateStructured,
|
|
4165
4745
|
windowHistory,
|
|
4166
4746
|
withAskTool,
|