@granular-software/sdk 0.4.49 → 0.4.50
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/agent-evals.d.mts +2 -2
- package/dist/agent-evals.d.ts +2 -2
- package/dist/agent-evals.js +1107 -103
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +1107 -103
- package/dist/agent-evals.mjs.map +1 -1
- package/dist/agent-harness.d.mts +19 -2
- package/dist/agent-harness.d.ts +19 -2
- package/dist/agent-harness.js +79 -26
- package/dist/agent-harness.js.map +1 -1
- package/dist/agent-harness.mjs +78 -27
- package/dist/agent-harness.mjs.map +1 -1
- package/dist/cli/index.js +1008 -66
- package/dist/{client-B-MPVvDr.d.mts → client-BbI7ThzU.d.ts} +62 -1
- package/dist/{client-zihxkDDs.d.ts → client-DaYFTHG8.d.mts} +62 -1
- package/dist/index.d.mts +104 -5
- package/dist/index.d.ts +104 -5
- package/dist/index.js +1189 -94
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1186 -95
- package/dist/index.mjs.map +1 -1
- package/dist/{spend-CStuOBXb.d.mts → spend-RpJikX9w.d.mts} +383 -11
- package/dist/{spend-CStuOBXb.d.ts → spend-RpJikX9w.d.ts} +383 -11
- package/dist/spend.d.mts +1 -1
- package/dist/spend.d.ts +1 -1
- package/package.json +2 -1
package/dist/cli/index.js
CHANGED
|
@@ -9880,7 +9880,7 @@ function relationshipEdgesForClass(className, rels) {
|
|
|
9880
9880
|
return edges;
|
|
9881
9881
|
}
|
|
9882
9882
|
function toPascalCase(name) {
|
|
9883
|
-
return name.charAt(0).toUpperCase() +
|
|
9883
|
+
return name.split(/[_:\-\s]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
9884
9884
|
}
|
|
9885
9885
|
|
|
9886
9886
|
// src/cli/agent-docs/concept-blocks.ts
|
|
@@ -14065,16 +14065,107 @@ var StateMachineStateSchema = external_exports.union([
|
|
|
14065
14065
|
external_exports.string(),
|
|
14066
14066
|
external_exports.object({
|
|
14067
14067
|
name: external_exports.string().min(1),
|
|
14068
|
+
label: external_exports.string().optional(),
|
|
14069
|
+
description: external_exports.string().optional(),
|
|
14068
14070
|
isFinal: external_exports.boolean().optional()
|
|
14069
14071
|
}).strict()
|
|
14070
14072
|
]);
|
|
14073
|
+
var StateTransitionInputBindingSchema = external_exports.lazy(
|
|
14074
|
+
() => external_exports.union([
|
|
14075
|
+
external_exports.null(),
|
|
14076
|
+
external_exports.string(),
|
|
14077
|
+
external_exports.number(),
|
|
14078
|
+
external_exports.boolean(),
|
|
14079
|
+
external_exports.array(StateTransitionInputBindingSchema),
|
|
14080
|
+
external_exports.object({
|
|
14081
|
+
const: external_exports.unknown()
|
|
14082
|
+
}).strict(),
|
|
14083
|
+
external_exports.object({
|
|
14084
|
+
from: external_exports.literal("object"),
|
|
14085
|
+
path: external_exports.string().min(1),
|
|
14086
|
+
editable: external_exports.boolean().optional()
|
|
14087
|
+
}).strict(),
|
|
14088
|
+
external_exports.object({
|
|
14089
|
+
from: external_exports.literal("field"),
|
|
14090
|
+
name: external_exports.string().min(1),
|
|
14091
|
+
editable: external_exports.boolean().optional()
|
|
14092
|
+
}).strict(),
|
|
14093
|
+
external_exports.object({
|
|
14094
|
+
from: external_exports.literal("relationship"),
|
|
14095
|
+
name: external_exports.string().min(1),
|
|
14096
|
+
path: external_exports.string().min(1).optional(),
|
|
14097
|
+
many: external_exports.boolean().optional(),
|
|
14098
|
+
editable: external_exports.boolean().optional()
|
|
14099
|
+
}).strict(),
|
|
14100
|
+
external_exports.object({
|
|
14101
|
+
from: external_exports.literal("session"),
|
|
14102
|
+
path: external_exports.string().min(1),
|
|
14103
|
+
editable: external_exports.boolean().optional()
|
|
14104
|
+
}).strict(),
|
|
14105
|
+
external_exports.object({
|
|
14106
|
+
from: external_exports.literal("actor"),
|
|
14107
|
+
path: external_exports.string().min(1),
|
|
14108
|
+
editable: external_exports.boolean().optional()
|
|
14109
|
+
}).strict(),
|
|
14110
|
+
external_exports.record(external_exports.string(), StateTransitionInputBindingSchema)
|
|
14111
|
+
])
|
|
14112
|
+
);
|
|
14113
|
+
var StateTransitionActionSchema = external_exports.object({
|
|
14114
|
+
effect: external_exports.string().min(1),
|
|
14115
|
+
input: external_exports.record(external_exports.string(), StateTransitionInputBindingSchema).optional()
|
|
14116
|
+
}).strict();
|
|
14117
|
+
var StateTransitionAssigneeSchema = external_exports.object({
|
|
14118
|
+
kind: external_exports.string().min(1),
|
|
14119
|
+
from: StateTransitionInputBindingSchema.optional(),
|
|
14120
|
+
role: external_exports.string().optional(),
|
|
14121
|
+
label: external_exports.string().optional()
|
|
14122
|
+
}).strict();
|
|
14123
|
+
var StateTransitionRelatedStateRequirementSchema = external_exports.object({
|
|
14124
|
+
relationship: external_exports.string().min(1),
|
|
14125
|
+
machine: external_exports.string().min(1),
|
|
14126
|
+
state: external_exports.string().min(1),
|
|
14127
|
+
className: external_exports.string().min(1).optional(),
|
|
14128
|
+
label: external_exports.string().optional(),
|
|
14129
|
+
mode: external_exports.enum(["every", "some", "any"]).optional()
|
|
14130
|
+
}).strict();
|
|
14131
|
+
var StateTransitionRequirementsSchema = external_exports.object({
|
|
14132
|
+
fields: external_exports.array(external_exports.string().min(1)).optional(),
|
|
14133
|
+
relationships: external_exports.array(external_exports.string().min(1)).optional(),
|
|
14134
|
+
relatedStates: external_exports.array(StateTransitionRelatedStateRequirementSchema).optional()
|
|
14135
|
+
}).strict();
|
|
14136
|
+
var StateTransitionPermissionSchema = external_exports.union([
|
|
14137
|
+
external_exports.string().min(1),
|
|
14138
|
+
external_exports.object({
|
|
14139
|
+
profile: external_exports.string().min(1).optional(),
|
|
14140
|
+
profileId: external_exports.string().min(1).optional(),
|
|
14141
|
+
label: external_exports.string().optional(),
|
|
14142
|
+
reason: external_exports.string().optional()
|
|
14143
|
+
}).strict()
|
|
14144
|
+
]);
|
|
14145
|
+
var StateTransitionExpectedOutcomeSchema = external_exports.union([
|
|
14146
|
+
external_exports.string().min(1),
|
|
14147
|
+
external_exports.object({
|
|
14148
|
+
machine: external_exports.string().min(1).optional(),
|
|
14149
|
+
state: external_exports.string().min(1),
|
|
14150
|
+
summary: external_exports.string().optional()
|
|
14151
|
+
}).strict()
|
|
14152
|
+
]);
|
|
14071
14153
|
var StateMachineTransitionSchema = external_exports.object({
|
|
14072
14154
|
name: external_exports.string().min(1),
|
|
14073
14155
|
from: external_exports.string().min(1),
|
|
14074
|
-
to: external_exports.string().min(1)
|
|
14156
|
+
to: external_exports.string().min(1),
|
|
14157
|
+
label: external_exports.string().optional(),
|
|
14158
|
+
description: external_exports.string().optional(),
|
|
14159
|
+
action: StateTransitionActionSchema.optional(),
|
|
14160
|
+
assignee: StateTransitionAssigneeSchema.optional(),
|
|
14161
|
+
requirements: StateTransitionRequirementsSchema.optional(),
|
|
14162
|
+
permission: StateTransitionPermissionSchema.optional(),
|
|
14163
|
+
risk: external_exports.enum(["low", "medium", "high"]).optional(),
|
|
14164
|
+
expectedOutcome: StateTransitionExpectedOutcomeSchema.optional()
|
|
14075
14165
|
}).strict();
|
|
14076
14166
|
external_exports.object({
|
|
14077
14167
|
name: external_exports.string().min(1),
|
|
14168
|
+
stateField: external_exports.string().min(1).optional(),
|
|
14078
14169
|
entryState: external_exports.string().min(1),
|
|
14079
14170
|
states: external_exports.array(StateMachineStateSchema).min(1),
|
|
14080
14171
|
transitions: external_exports.array(StateMachineTransitionSchema),
|
|
@@ -14141,6 +14232,16 @@ var PoliciesSchema = external_exports.object({
|
|
|
14141
14232
|
confirmWhen: external_exports.array(PolicyRuleSchema).optional(),
|
|
14142
14233
|
denyWhen: external_exports.array(PolicyRuleSchema).optional()
|
|
14143
14234
|
}).strict();
|
|
14235
|
+
var CreatesSchema = external_exports.union([
|
|
14236
|
+
external_exports.string().min(1),
|
|
14237
|
+
external_exports.object({
|
|
14238
|
+
className: external_exports.string().min(1),
|
|
14239
|
+
idPath: external_exports.string().min(1).optional(),
|
|
14240
|
+
pathPath: external_exports.string().min(1).optional(),
|
|
14241
|
+
statePath: external_exports.string().min(1).optional(),
|
|
14242
|
+
classStateHandle: external_exports.boolean().optional()
|
|
14243
|
+
}).strict()
|
|
14244
|
+
]);
|
|
14144
14245
|
external_exports.object({
|
|
14145
14246
|
postCondition: external_exports.union([
|
|
14146
14247
|
external_exports.string(),
|
|
@@ -14171,6 +14272,7 @@ external_exports.object({
|
|
|
14171
14272
|
mode: external_exports.string().optional()
|
|
14172
14273
|
}).strict()
|
|
14173
14274
|
]).optional(),
|
|
14275
|
+
creates: CreatesSchema.optional(),
|
|
14174
14276
|
access: external_exports.enum(["read", "write", "ui"]).optional(),
|
|
14175
14277
|
effectKind: external_exports.enum(["read", "write", "ui"]).optional(),
|
|
14176
14278
|
sideEffect: external_exports.enum(["read", "write", "ui", "readonly", "read_only"]).optional(),
|
|
@@ -14398,6 +14500,7 @@ function mergeMethodSummaryPatch(target, patch) {
|
|
|
14398
14500
|
if (patch.metamodels !== void 0) target.metamodels = patch.metamodels;
|
|
14399
14501
|
if (patch.effectBehaviors !== void 0)
|
|
14400
14502
|
target.effectBehaviors = patch.effectBehaviors;
|
|
14503
|
+
if (patch.creates !== void 0) target.creates = patch.creates;
|
|
14401
14504
|
if (patch.static !== void 0) target.static = patch.static;
|
|
14402
14505
|
}
|
|
14403
14506
|
function toPascalCase2(value) {
|
|
@@ -14458,29 +14561,60 @@ function normalizeEffectBehaviorSummary(metamodels) {
|
|
|
14458
14561
|
}
|
|
14459
14562
|
return Object.keys(result).length > 0 ? result : null;
|
|
14460
14563
|
}
|
|
14461
|
-
function
|
|
14462
|
-
if (!
|
|
14463
|
-
|
|
14564
|
+
function normalizeCreationSummary(metamodels) {
|
|
14565
|
+
if (!isObject(metamodels)) return null;
|
|
14566
|
+
let raw = metamodels.creates;
|
|
14567
|
+
if (typeof raw === "string" && raw.trim().length > 0) {
|
|
14568
|
+
const trimmed = raw.trim();
|
|
14569
|
+
if (trimmed.startsWith("{") || trimmed.startsWith('"')) {
|
|
14570
|
+
try {
|
|
14571
|
+
raw = JSON.parse(trimmed);
|
|
14572
|
+
} catch {
|
|
14573
|
+
return { className: trimmed };
|
|
14574
|
+
}
|
|
14575
|
+
} else {
|
|
14576
|
+
return { className: trimmed };
|
|
14577
|
+
}
|
|
14464
14578
|
}
|
|
14579
|
+
if (typeof raw === "string" && raw.trim().length > 0) {
|
|
14580
|
+
return { className: raw.trim() };
|
|
14581
|
+
}
|
|
14582
|
+
if (!isObject(raw)) return null;
|
|
14583
|
+
const className = typeof raw.className === "string" && raw.className.trim() ? raw.className.trim() : "";
|
|
14584
|
+
if (!className) return null;
|
|
14585
|
+
return {
|
|
14586
|
+
className,
|
|
14587
|
+
...typeof raw.idPath === "string" && raw.idPath.trim() ? { idPath: raw.idPath.trim() } : {},
|
|
14588
|
+
...typeof raw.pathPath === "string" && raw.pathPath.trim() ? { pathPath: raw.pathPath.trim() } : {},
|
|
14589
|
+
...typeof raw.statePath === "string" && raw.statePath.trim() ? { statePath: raw.statePath.trim() } : {},
|
|
14590
|
+
...typeof raw.classStateHandle === "boolean" ? { classStateHandle: raw.classStateHandle } : {}
|
|
14591
|
+
};
|
|
14592
|
+
}
|
|
14593
|
+
function buildEffectBehaviorDocs(effectBehaviors, creates) {
|
|
14465
14594
|
const docs = [];
|
|
14466
|
-
if (
|
|
14595
|
+
if (creates) {
|
|
14596
|
+
docs.push(
|
|
14597
|
+
`Creation method: creates ${creates.className}. The agent may use generated class-level new-record action methods for this class.`
|
|
14598
|
+
);
|
|
14599
|
+
}
|
|
14600
|
+
if (effectBehaviors?.approvalRequired?.required) {
|
|
14467
14601
|
docs.push(
|
|
14468
14602
|
effectBehaviors.approvalRequired.reason ? `Approval required: ${effectBehaviors.approvalRequired.reason}.` : "Approval required before execution."
|
|
14469
14603
|
);
|
|
14470
14604
|
}
|
|
14471
|
-
if (effectBehaviors
|
|
14605
|
+
if (effectBehaviors?.postCondition) {
|
|
14472
14606
|
docs.push(`Post-condition: ${effectBehaviors.postCondition.condition}.`);
|
|
14473
14607
|
if (effectBehaviors.postCondition.description) {
|
|
14474
14608
|
docs.push(effectBehaviors.postCondition.description);
|
|
14475
14609
|
}
|
|
14476
14610
|
}
|
|
14477
|
-
if (effectBehaviors
|
|
14611
|
+
if (effectBehaviors?.dryRun?.enabled) {
|
|
14478
14612
|
docs.push("Supports dry run.");
|
|
14479
14613
|
if (effectBehaviors.dryRun.description) {
|
|
14480
14614
|
docs.push(effectBehaviors.dryRun.description);
|
|
14481
14615
|
}
|
|
14482
14616
|
}
|
|
14483
|
-
if (effectBehaviors
|
|
14617
|
+
if (effectBehaviors?.reverse) {
|
|
14484
14618
|
if (effectBehaviors.reverse.handler) {
|
|
14485
14619
|
docs.push(`Reverse handler: ${effectBehaviors.reverse.handler}.`);
|
|
14486
14620
|
} else {
|
|
@@ -14539,13 +14673,21 @@ function buildEffectBehaviorMutations(toolPath, spec) {
|
|
|
14539
14673
|
query: `mutation { at(path: ${JSON.stringify(toolPath)}) { set_approval_required(${args}) { kind } } }`
|
|
14540
14674
|
});
|
|
14541
14675
|
}
|
|
14676
|
+
if (spec.creates !== void 0) {
|
|
14677
|
+
mutations.push({
|
|
14678
|
+
label: `set creates on ${toolPath}`,
|
|
14679
|
+
query: `mutation { at(path: ${JSON.stringify(toolPath)}) { create_submodel(subpath: "creates", label: "creates") { set_string_value(value: ${JSON.stringify(
|
|
14680
|
+
JSON.stringify(spec.creates)
|
|
14681
|
+
)}) { done } } } }`
|
|
14682
|
+
});
|
|
14683
|
+
}
|
|
14542
14684
|
return mutations;
|
|
14543
14685
|
}
|
|
14544
14686
|
function readMethodEffectBehaviors(rawMethod) {
|
|
14687
|
+
const metamodels = isObject(rawMethod.metamodels) ? rawMethod.metamodels : null;
|
|
14545
14688
|
return {
|
|
14546
|
-
effectBehaviors: normalizeEffectBehaviorSummary(
|
|
14547
|
-
|
|
14548
|
-
)
|
|
14689
|
+
effectBehaviors: normalizeEffectBehaviorSummary(metamodels),
|
|
14690
|
+
creates: normalizeCreationSummary(metamodels)
|
|
14549
14691
|
};
|
|
14550
14692
|
}
|
|
14551
14693
|
var effectBehaviorsMetamodelPackage = defineMetamodelPackage({
|
|
@@ -14567,6 +14709,10 @@ var effectBehaviorsMetamodelPackage = defineMetamodelPackage({
|
|
|
14567
14709
|
{
|
|
14568
14710
|
key: "approvalRequired",
|
|
14569
14711
|
description: "Boolean or `{ required, reason, mode }`."
|
|
14712
|
+
},
|
|
14713
|
+
{
|
|
14714
|
+
key: "creates",
|
|
14715
|
+
description: 'Marks a static method as an allowed creator for a class. Use `creates: "class_name"` or `{ className, idPath, pathPath, statePath, classStateHandle }`.'
|
|
14570
14716
|
}
|
|
14571
14717
|
]
|
|
14572
14718
|
},
|
|
@@ -14686,7 +14832,10 @@ var effectBehaviorsMetamodelPackage = defineMetamodelPackage({
|
|
|
14686
14832
|
...methodIR,
|
|
14687
14833
|
docs: [
|
|
14688
14834
|
...methodIR.docs,
|
|
14689
|
-
...buildEffectBehaviorDocs(
|
|
14835
|
+
...buildEffectBehaviorDocs(
|
|
14836
|
+
methodSummary.effectBehaviors,
|
|
14837
|
+
methodSummary.creates
|
|
14838
|
+
)
|
|
14690
14839
|
]
|
|
14691
14840
|
};
|
|
14692
14841
|
}
|
|
@@ -15305,15 +15454,47 @@ var searchableMetamodelPackage = defineMetamodelPackage({
|
|
|
15305
15454
|
|
|
15306
15455
|
// ../metamodel-state-machine/src/index.ts
|
|
15307
15456
|
function normalizeStateMachines(values) {
|
|
15457
|
+
const parseJsonRecord = (value) => {
|
|
15458
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
15459
|
+
return value;
|
|
15460
|
+
}
|
|
15461
|
+
if (typeof value !== "string" || !value.trim()) return null;
|
|
15462
|
+
try {
|
|
15463
|
+
const parsed = JSON.parse(value);
|
|
15464
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
15465
|
+
} catch {
|
|
15466
|
+
return null;
|
|
15467
|
+
}
|
|
15468
|
+
};
|
|
15469
|
+
const parseJsonValue = (value) => {
|
|
15470
|
+
if (value === null || typeof value === "undefined") return null;
|
|
15471
|
+
if (typeof value !== "string") return value;
|
|
15472
|
+
if (!value.trim()) return null;
|
|
15473
|
+
try {
|
|
15474
|
+
return JSON.parse(value);
|
|
15475
|
+
} catch {
|
|
15476
|
+
return value;
|
|
15477
|
+
}
|
|
15478
|
+
};
|
|
15308
15479
|
return (values || []).map((machine) => {
|
|
15309
15480
|
const states = (machine?.states || []).map((state) => ({
|
|
15310
15481
|
name: String(state?.name || ""),
|
|
15311
|
-
|
|
15482
|
+
label: typeof state?.label === "string" ? state.label : null,
|
|
15483
|
+
description: typeof state?.description === "string" ? state.description : null,
|
|
15484
|
+
isFinal: Boolean(state?.is_final ?? state?.isFinal)
|
|
15312
15485
|
})).filter((state) => state.name.length > 0);
|
|
15313
15486
|
const transitions = (machine?.transitions || []).map((transition) => ({
|
|
15314
15487
|
name: String(transition?.name || ""),
|
|
15315
15488
|
from: String(transition?.from?.name || ""),
|
|
15316
|
-
to: String(transition?.to?.name || "")
|
|
15489
|
+
to: String(transition?.to?.name || ""),
|
|
15490
|
+
label: typeof transition?.label === "string" ? transition.label : null,
|
|
15491
|
+
description: typeof transition?.description === "string" ? transition.description : null,
|
|
15492
|
+
action: parseJsonRecord(transition?.action) || parseJsonRecord(transition?.action_json),
|
|
15493
|
+
assignee: parseJsonRecord(transition?.assignee) || parseJsonRecord(transition?.assignee_json),
|
|
15494
|
+
requirements: parseJsonRecord(transition?.requirements) || parseJsonRecord(transition?.requirements_json),
|
|
15495
|
+
permission: parseJsonValue(transition?.permission) ?? parseJsonValue(transition?.permission_json),
|
|
15496
|
+
risk: transition?.risk === "low" || transition?.risk === "medium" || transition?.risk === "high" ? transition.risk : null,
|
|
15497
|
+
expectedOutcome: parseJsonValue(transition?.expectedOutcome) ?? parseJsonValue(transition?.expected_outcome_json)
|
|
15317
15498
|
})).filter(
|
|
15318
15499
|
(transition) => transition.name.length > 0 && transition.from.length > 0 && transition.to.length > 0
|
|
15319
15500
|
);
|
|
@@ -15335,6 +15516,15 @@ function transitionTypeName(className, machineName) {
|
|
|
15335
15516
|
function pathTypeName(className, machineName) {
|
|
15336
15517
|
return `${stateTypeName(className, machineName)}Path`;
|
|
15337
15518
|
}
|
|
15519
|
+
function methodToken(value) {
|
|
15520
|
+
const token = String(value || "").trim().replace(/[^A-Za-z0-9_]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
15521
|
+
return token || "state";
|
|
15522
|
+
}
|
|
15523
|
+
function transitionActionsForMachine(machine) {
|
|
15524
|
+
return Object.fromEntries(
|
|
15525
|
+
(machine.transitions || []).filter((transition) => transition.action?.effect).map((transition) => [transition.name, transition.action])
|
|
15526
|
+
);
|
|
15527
|
+
}
|
|
15338
15528
|
function normalizeStateDefinitions(machine) {
|
|
15339
15529
|
const finalStates = new Set(machine.finalStates || []);
|
|
15340
15530
|
const states = /* @__PURE__ */ new Map();
|
|
@@ -15348,6 +15538,8 @@ function normalizeStateDefinitions(machine) {
|
|
|
15348
15538
|
}
|
|
15349
15539
|
states.set(rawState.name, {
|
|
15350
15540
|
name: rawState.name,
|
|
15541
|
+
label: rawState.label,
|
|
15542
|
+
description: rawState.description,
|
|
15351
15543
|
isFinal: Boolean(rawState.isFinal) || finalStates.has(rawState.name)
|
|
15352
15544
|
});
|
|
15353
15545
|
}
|
|
@@ -15359,6 +15551,44 @@ function normalizeStateDefinitions(machine) {
|
|
|
15359
15551
|
}
|
|
15360
15552
|
return [...states.values()];
|
|
15361
15553
|
}
|
|
15554
|
+
function transitionMetadataGraphqlArgs(transition) {
|
|
15555
|
+
const args = [];
|
|
15556
|
+
if (typeof transition.label === "string") {
|
|
15557
|
+
args.push(`label: ${JSON.stringify(transition.label)}`);
|
|
15558
|
+
}
|
|
15559
|
+
if (typeof transition.description === "string") {
|
|
15560
|
+
args.push(`description: ${JSON.stringify(transition.description)}`);
|
|
15561
|
+
}
|
|
15562
|
+
if (transition.action) {
|
|
15563
|
+
args.push(
|
|
15564
|
+
`action_json: ${JSON.stringify(JSON.stringify(transition.action))}`
|
|
15565
|
+
);
|
|
15566
|
+
}
|
|
15567
|
+
if (transition.assignee) {
|
|
15568
|
+
args.push(
|
|
15569
|
+
`assignee_json: ${JSON.stringify(JSON.stringify(transition.assignee))}`
|
|
15570
|
+
);
|
|
15571
|
+
}
|
|
15572
|
+
if (transition.requirements) {
|
|
15573
|
+
args.push(
|
|
15574
|
+
`requirements_json: ${JSON.stringify(JSON.stringify(transition.requirements))}`
|
|
15575
|
+
);
|
|
15576
|
+
}
|
|
15577
|
+
if (transition.permission) {
|
|
15578
|
+
args.push(
|
|
15579
|
+
`permission_json: ${JSON.stringify(JSON.stringify(transition.permission))}`
|
|
15580
|
+
);
|
|
15581
|
+
}
|
|
15582
|
+
if (transition.risk) {
|
|
15583
|
+
args.push(`risk: ${JSON.stringify(transition.risk)}`);
|
|
15584
|
+
}
|
|
15585
|
+
if (transition.expectedOutcome) {
|
|
15586
|
+
args.push(
|
|
15587
|
+
`expected_outcome_json: ${JSON.stringify(JSON.stringify(transition.expectedOutcome))}`
|
|
15588
|
+
);
|
|
15589
|
+
}
|
|
15590
|
+
return args.length > 0 ? `, ${args.join(", ")}` : "";
|
|
15591
|
+
}
|
|
15362
15592
|
function buildStateMachineModelMutations(modelPath, machines) {
|
|
15363
15593
|
const mutations = [];
|
|
15364
15594
|
for (const machine of machines || []) {
|
|
@@ -15369,12 +15599,13 @@ function buildStateMachineModelMutations(modelPath, machines) {
|
|
|
15369
15599
|
)}, entry_state: ${JSON.stringify(machine.entryState)}) { name } } }`
|
|
15370
15600
|
});
|
|
15371
15601
|
for (const state of normalizeStateDefinitions(machine)) {
|
|
15372
|
-
if (state.name === machine.entryState && !state.isFinal)
|
|
15602
|
+
if (state.name === machine.entryState && !state.isFinal && !state.label && !state.description)
|
|
15603
|
+
continue;
|
|
15373
15604
|
mutations.push({
|
|
15374
15605
|
label: `add state ${state.name} on ${modelPath}.${machine.name}`,
|
|
15375
15606
|
query: `mutation { at(path: ${JSON.stringify(modelPath)}) { state_machine(name: ${JSON.stringify(
|
|
15376
15607
|
machine.name
|
|
15377
|
-
)}) { add_state(name: ${JSON.stringify(state.name)}, is_final: ${state.isFinal}) { name } } } }`
|
|
15608
|
+
)}) { add_state(name: ${JSON.stringify(state.name)}, is_final: ${state.isFinal}, label: ${JSON.stringify(state.label || null)}, description: ${JSON.stringify(state.description || null)}) { name } } } }`
|
|
15378
15609
|
});
|
|
15379
15610
|
}
|
|
15380
15611
|
for (const transition of machine.transitions || []) {
|
|
@@ -15386,7 +15617,7 @@ function buildStateMachineModelMutations(modelPath, machines) {
|
|
|
15386
15617
|
transition.name
|
|
15387
15618
|
)}, from: ${JSON.stringify(transition.from)}, to: ${JSON.stringify(
|
|
15388
15619
|
transition.to
|
|
15389
|
-
)}) { name } } } }`
|
|
15620
|
+
)}${transitionMetadataGraphqlArgs(transition)}) { name } } } }`
|
|
15390
15621
|
});
|
|
15391
15622
|
}
|
|
15392
15623
|
}
|
|
@@ -15413,7 +15644,7 @@ function buildMachineMethods(classSummary, machine) {
|
|
|
15413
15644
|
const transitionName = transitionTypeName(classSummary.name, machine.name);
|
|
15414
15645
|
pathTypeName(classSummary.name, machine.name);
|
|
15415
15646
|
const docsPrefix = `${classSummary.name}.${machine.name}`;
|
|
15416
|
-
|
|
15647
|
+
const methods = [
|
|
15417
15648
|
{
|
|
15418
15649
|
name: `get_${machine.name}`,
|
|
15419
15650
|
docs: [`Get the current ${docsPrefix} state.`],
|
|
@@ -15509,6 +15740,99 @@ function buildMachineMethods(classSummary, machine) {
|
|
|
15509
15740
|
}
|
|
15510
15741
|
}
|
|
15511
15742
|
];
|
|
15743
|
+
const creationMethods = (classSummary.methods || []).filter(
|
|
15744
|
+
(method) => method.static === true && Boolean(method.creates) && method.creates?.className === classSummary.name && typeof method.effectKey === "string" && method.effectKey.length > 0
|
|
15745
|
+
);
|
|
15746
|
+
for (const state of machine.states) {
|
|
15747
|
+
const stateNameValue = typeof state === "string" ? state : String(state?.name || "");
|
|
15748
|
+
if (!stateNameValue) continue;
|
|
15749
|
+
const token = methodToken(stateNameValue);
|
|
15750
|
+
methods.push(
|
|
15751
|
+
{
|
|
15752
|
+
name: `reach_${machine.name}_to_${token}`,
|
|
15753
|
+
docs: [`Reach ${docsPrefix} state ${stateNameValue}.`],
|
|
15754
|
+
static: false,
|
|
15755
|
+
params: [],
|
|
15756
|
+
returnType: `Promise<${toPascalCase2(classSummary.name)}>`,
|
|
15757
|
+
runtime: {
|
|
15758
|
+
kind: "state_machine",
|
|
15759
|
+
machineName: machine.name,
|
|
15760
|
+
className: classSummary.name,
|
|
15761
|
+
stateTypeName: stateName,
|
|
15762
|
+
transitionTypeName: transitionName,
|
|
15763
|
+
operation: "reach",
|
|
15764
|
+
targetState: stateNameValue,
|
|
15765
|
+
transitionActions: transitionActionsForMachine(machine)
|
|
15766
|
+
}
|
|
15767
|
+
},
|
|
15768
|
+
{
|
|
15769
|
+
name: `prepare_${machine.name}_to_${token}`,
|
|
15770
|
+
docs: [
|
|
15771
|
+
`Prepare a reviewable artifact that can move ${docsPrefix} to ${stateNameValue}.`
|
|
15772
|
+
],
|
|
15773
|
+
static: false,
|
|
15774
|
+
params: [],
|
|
15775
|
+
returnType: "Promise<SessionArtifactRecord>",
|
|
15776
|
+
runtime: {
|
|
15777
|
+
kind: "state_machine",
|
|
15778
|
+
machineName: machine.name,
|
|
15779
|
+
className: classSummary.name,
|
|
15780
|
+
stateTypeName: stateName,
|
|
15781
|
+
transitionTypeName: transitionName,
|
|
15782
|
+
operation: "prepare_reach",
|
|
15783
|
+
targetState: stateNameValue,
|
|
15784
|
+
transitionActions: transitionActionsForMachine(machine)
|
|
15785
|
+
}
|
|
15786
|
+
}
|
|
15787
|
+
);
|
|
15788
|
+
for (const creationMethod of creationMethods) {
|
|
15789
|
+
const creationRuntime = {
|
|
15790
|
+
kind: "state_machine",
|
|
15791
|
+
machineName: machine.name,
|
|
15792
|
+
className: classSummary.name,
|
|
15793
|
+
stateTypeName: stateName,
|
|
15794
|
+
transitionTypeName: transitionName,
|
|
15795
|
+
operation: "prepare_create_reach",
|
|
15796
|
+
targetState: stateNameValue,
|
|
15797
|
+
transitionActions: transitionActionsForMachine(machine),
|
|
15798
|
+
creation: {
|
|
15799
|
+
methodName: creationMethod.name,
|
|
15800
|
+
effectKey: creationMethod.effectKey || creationMethod.name,
|
|
15801
|
+
inputSchema: creationMethod.inputSchema,
|
|
15802
|
+
outputSchema: creationMethod.outputSchema,
|
|
15803
|
+
creates: creationMethod.creates
|
|
15804
|
+
}
|
|
15805
|
+
};
|
|
15806
|
+
const viaName = `prepare_${machine.name}_to_${token}_via_${methodToken(creationMethod.name)}`;
|
|
15807
|
+
methods.push({
|
|
15808
|
+
name: viaName,
|
|
15809
|
+
docs: [
|
|
15810
|
+
`Prepare a reviewable artifact that will create a new ${classSummary.name} through ${creationMethod.name}, then move ${docsPrefix} to ${stateNameValue}.`
|
|
15811
|
+
],
|
|
15812
|
+
static: true,
|
|
15813
|
+
params: [
|
|
15814
|
+
{ name: "input", type: "Record<string, any>", optional: true }
|
|
15815
|
+
],
|
|
15816
|
+
returnType: "Promise<SessionArtifactRecord>",
|
|
15817
|
+
runtime: creationRuntime
|
|
15818
|
+
});
|
|
15819
|
+
if (creationMethods.length === 1) {
|
|
15820
|
+
methods.push({
|
|
15821
|
+
name: `prepare_${machine.name}_to_${token}`,
|
|
15822
|
+
docs: [
|
|
15823
|
+
`Prepare a reviewable artifact that will create a new ${classSummary.name}, then move ${docsPrefix} to ${stateNameValue}.`
|
|
15824
|
+
],
|
|
15825
|
+
static: true,
|
|
15826
|
+
params: [
|
|
15827
|
+
{ name: "input", type: "Record<string, any>", optional: true }
|
|
15828
|
+
],
|
|
15829
|
+
returnType: "Promise<SessionArtifactRecord>",
|
|
15830
|
+
runtime: creationRuntime
|
|
15831
|
+
});
|
|
15832
|
+
}
|
|
15833
|
+
}
|
|
15834
|
+
}
|
|
15835
|
+
return methods;
|
|
15512
15836
|
}
|
|
15513
15837
|
function readStateMachineSummaries(rawClass) {
|
|
15514
15838
|
return {
|
|
@@ -15531,8 +15855,8 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
15531
15855
|
type StateMachineMutation {
|
|
15532
15856
|
name: String!
|
|
15533
15857
|
state_machine: StateMachine!
|
|
15534
|
-
add_state(name: String!, is_final: Boolean): StateMachineMutation!
|
|
15535
|
-
add_transition(name: String!, from: String!, to: String
|
|
15858
|
+
add_state(name: String!, is_final: Boolean, label: String, description: String): StateMachineMutation!
|
|
15859
|
+
add_transition(name: String!, from: String!, to: String!, label: String, description: String, action_json: String, assignee_json: String, requirements_json: String, permission_json: String, risk: String, expected_outcome_json: String): StateMachineMutation!
|
|
15536
15860
|
activate_transition(name: String!): StateMachineMutation!
|
|
15537
15861
|
}
|
|
15538
15862
|
|
|
@@ -15549,6 +15873,7 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
15549
15873
|
type StateMachineSnapshotMutation {
|
|
15550
15874
|
snapshot: StateMachineSnapshot!
|
|
15551
15875
|
activate_transition(name: String!): StateMachineSnapshotMutation!
|
|
15876
|
+
observe_state(state: String!, force: Boolean, source: String): StateMachineSnapshotMutation!
|
|
15552
15877
|
}
|
|
15553
15878
|
|
|
15554
15879
|
type StateMachine {
|
|
@@ -15568,6 +15893,8 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
15568
15893
|
|
|
15569
15894
|
type StateMachineState {
|
|
15570
15895
|
name: String!
|
|
15896
|
+
label: String
|
|
15897
|
+
description: String
|
|
15571
15898
|
is_final: Boolean!
|
|
15572
15899
|
}
|
|
15573
15900
|
|
|
@@ -15575,6 +15902,14 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
15575
15902
|
name: String!
|
|
15576
15903
|
from: StateMachineState!
|
|
15577
15904
|
to: StateMachineState!
|
|
15905
|
+
label: String
|
|
15906
|
+
description: String
|
|
15907
|
+
action_json: String
|
|
15908
|
+
assignee_json: String
|
|
15909
|
+
requirements_json: String
|
|
15910
|
+
permission_json: String
|
|
15911
|
+
risk: String
|
|
15912
|
+
expected_outcome_json: String
|
|
15578
15913
|
}
|
|
15579
15914
|
|
|
15580
15915
|
type StateMachinePath {
|
|
@@ -15627,23 +15962,47 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
15627
15962
|
StateMachineMutation: {
|
|
15628
15963
|
name: (value) => value.name,
|
|
15629
15964
|
state_machine: async (value) => await run(value.target.state_machine(value.name)),
|
|
15630
|
-
add_state: async (value, { name, is_final }) => {
|
|
15965
|
+
add_state: async (value, { name, is_final, label, description }) => {
|
|
15631
15966
|
await run(
|
|
15632
15967
|
value.target.add_state_machine_state(
|
|
15633
15968
|
value.name,
|
|
15634
15969
|
name,
|
|
15635
|
-
is_final ?? false
|
|
15970
|
+
is_final ?? false,
|
|
15971
|
+
label,
|
|
15972
|
+
description
|
|
15636
15973
|
)
|
|
15637
15974
|
);
|
|
15638
15975
|
return value;
|
|
15639
15976
|
},
|
|
15640
|
-
add_transition: async (value, {
|
|
15977
|
+
add_transition: async (value, {
|
|
15978
|
+
name,
|
|
15979
|
+
from,
|
|
15980
|
+
to,
|
|
15981
|
+
label,
|
|
15982
|
+
description,
|
|
15983
|
+
action_json,
|
|
15984
|
+
assignee_json,
|
|
15985
|
+
requirements_json,
|
|
15986
|
+
permission_json,
|
|
15987
|
+
risk,
|
|
15988
|
+
expected_outcome_json
|
|
15989
|
+
}) => {
|
|
15641
15990
|
await run(
|
|
15642
15991
|
value.target.add_state_machine_transition(
|
|
15643
15992
|
value.name,
|
|
15644
15993
|
name,
|
|
15645
15994
|
from,
|
|
15646
|
-
to
|
|
15995
|
+
to,
|
|
15996
|
+
{
|
|
15997
|
+
label,
|
|
15998
|
+
description,
|
|
15999
|
+
actionJson: action_json,
|
|
16000
|
+
assigneeJson: assignee_json,
|
|
16001
|
+
requirementsJson: requirements_json,
|
|
16002
|
+
permissionJson: permission_json,
|
|
16003
|
+
risk,
|
|
16004
|
+
expectedOutcomeJson: expected_outcome_json
|
|
16005
|
+
}
|
|
15647
16006
|
)
|
|
15648
16007
|
);
|
|
15649
16008
|
return value;
|
|
@@ -15662,16 +16021,37 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
15662
16021
|
value.target.activate_state_machine_transition(value.name, name)
|
|
15663
16022
|
);
|
|
15664
16023
|
return value;
|
|
16024
|
+
},
|
|
16025
|
+
observe_state: async (value, { state, force, source }) => {
|
|
16026
|
+
await run(
|
|
16027
|
+
value.target.observe_state_machine_state(
|
|
16028
|
+
value.name,
|
|
16029
|
+
state,
|
|
16030
|
+
force === true,
|
|
16031
|
+
source
|
|
16032
|
+
)
|
|
16033
|
+
);
|
|
16034
|
+
return value;
|
|
15665
16035
|
}
|
|
15666
16036
|
},
|
|
15667
16037
|
StateMachineState: {
|
|
15668
16038
|
name: (value) => value.name,
|
|
16039
|
+
label: (value) => value.label || null,
|
|
16040
|
+
description: (value) => value.description || null,
|
|
15669
16041
|
is_final: (value) => value.is_final
|
|
15670
16042
|
},
|
|
15671
16043
|
StateMachineTransition: {
|
|
15672
16044
|
name: (value) => value.name,
|
|
15673
16045
|
from: (value) => value.from_state || { name: value.from, is_final: false },
|
|
15674
|
-
to: (value) => value.to_state || { name: value.to, is_final: false }
|
|
16046
|
+
to: (value) => value.to_state || { name: value.to, is_final: false },
|
|
16047
|
+
label: (value) => value.label || null,
|
|
16048
|
+
description: (value) => value.description || null,
|
|
16049
|
+
action_json: (value) => value.action_json || null,
|
|
16050
|
+
assignee_json: (value) => value.assignee_json || null,
|
|
16051
|
+
requirements_json: (value) => value.requirements_json || null,
|
|
16052
|
+
permission_json: (value) => value.permission_json || null,
|
|
16053
|
+
risk: (value) => value.risk || null,
|
|
16054
|
+
expected_outcome_json: (value) => value.expected_outcome_json || null
|
|
15675
16055
|
},
|
|
15676
16056
|
StateMachinePath: {
|
|
15677
16057
|
states: (value) => value.states,
|
|
@@ -15738,6 +16118,14 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
15738
16118
|
name
|
|
15739
16119
|
from { name }
|
|
15740
16120
|
to { name }
|
|
16121
|
+
label
|
|
16122
|
+
description
|
|
16123
|
+
action_json
|
|
16124
|
+
assignee_json
|
|
16125
|
+
requirements_json
|
|
16126
|
+
permission_json
|
|
16127
|
+
risk
|
|
16128
|
+
expected_outcome_json
|
|
15741
16129
|
}
|
|
15742
16130
|
}`
|
|
15743
16131
|
]
|
|
@@ -19145,6 +19533,9 @@ function rpcTimeoutMsForMethod(method) {
|
|
|
19145
19533
|
return DOMAIN_PACKAGE_RPC_TIMEOUT_MS;
|
|
19146
19534
|
case "client.heartbeat":
|
|
19147
19535
|
case "effects.publishCatalog":
|
|
19536
|
+
case "effects.resetCatalog":
|
|
19537
|
+
case "effects.addCatalog":
|
|
19538
|
+
case "effects.removeCatalog":
|
|
19148
19539
|
case "effects.refresh":
|
|
19149
19540
|
return EFFECT_CONTROL_RPC_TIMEOUT_MS;
|
|
19150
19541
|
case "harness.run":
|
|
@@ -19890,6 +20281,9 @@ function resolvePromptAnswer(prompt3, answer) {
|
|
|
19890
20281
|
|
|
19891
20282
|
// src/session.ts
|
|
19892
20283
|
var PROMPT_TRANSCRIPT_APPEND_TIMEOUT_MS = 5e3;
|
|
20284
|
+
function toPascalCase3(value) {
|
|
20285
|
+
return value.split(/[_:\-\s]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
20286
|
+
}
|
|
19893
20287
|
function withPromptTranscriptTimeout(promise) {
|
|
19894
20288
|
let timeout = null;
|
|
19895
20289
|
return Promise.race([
|
|
@@ -20452,9 +20846,7 @@ var Session = class {
|
|
|
20452
20846
|
if (classes && Object.keys(classes).length > 0) {
|
|
20453
20847
|
let docs2 = "# Domain Documentation\n\n";
|
|
20454
20848
|
docs2 += "Import concrete classes from `@granular/domain/<Class>` and global backend actions from `@granular/actions/backend`:\n\n";
|
|
20455
|
-
const classNames = Object.keys(classes).map(
|
|
20456
|
-
(c) => c.charAt(0).toUpperCase() + c.slice(1)
|
|
20457
|
-
);
|
|
20849
|
+
const classNames = Object.keys(classes).map(toPascalCase3);
|
|
20458
20850
|
const globalNames = (globalTools || []).map((t) => t.name);
|
|
20459
20851
|
const importLines = [
|
|
20460
20852
|
...classNames.map(
|
|
@@ -20468,7 +20860,7 @@ ${importLines.join("\n") || "// No generated domain imports available."}
|
|
|
20468
20860
|
|
|
20469
20861
|
`;
|
|
20470
20862
|
for (const [className, cls] of Object.entries(classes)) {
|
|
20471
|
-
const TsName =
|
|
20863
|
+
const TsName = toPascalCase3(className);
|
|
20472
20864
|
docs2 += `## ${TsName}
|
|
20473
20865
|
|
|
20474
20866
|
`;
|
|
@@ -21458,6 +21850,28 @@ function asString(value) {
|
|
|
21458
21850
|
function trimString(value) {
|
|
21459
21851
|
return typeof value === "string" ? value.trim() : "";
|
|
21460
21852
|
}
|
|
21853
|
+
function compactJson(value, maxLength = 320) {
|
|
21854
|
+
if (value === void 0 || value === null) return void 0;
|
|
21855
|
+
try {
|
|
21856
|
+
const json = JSON.stringify(value);
|
|
21857
|
+
if (!json || json === "undefined") return void 0;
|
|
21858
|
+
return json.length > maxLength ? `${json.slice(0, maxLength)}...` : json;
|
|
21859
|
+
} catch {
|
|
21860
|
+
return String(value);
|
|
21861
|
+
}
|
|
21862
|
+
}
|
|
21863
|
+
function artifactRecordsById(liveDoc) {
|
|
21864
|
+
const artifacts = asRecord3(liveDoc?.artifacts);
|
|
21865
|
+
const byId = asRecord3(artifacts?.byId) || {};
|
|
21866
|
+
return Object.fromEntries(
|
|
21867
|
+
Object.entries(byId).map(([artifactId, value]) => {
|
|
21868
|
+
const record = asRecord3(value);
|
|
21869
|
+
return record ? [artifactId, record] : null;
|
|
21870
|
+
}).filter(
|
|
21871
|
+
(entry) => Boolean(entry)
|
|
21872
|
+
)
|
|
21873
|
+
);
|
|
21874
|
+
}
|
|
21461
21875
|
function normalizeShowRefs(value) {
|
|
21462
21876
|
const record = asRecord3(value);
|
|
21463
21877
|
if (!record) return void 0;
|
|
@@ -21474,9 +21888,31 @@ function normalizeShowRefs(value) {
|
|
|
21474
21888
|
entryPaths: normalizeRefs(record.entryPaths),
|
|
21475
21889
|
listNames: normalizeRefs(record.listNames),
|
|
21476
21890
|
variableNames: normalizeRefs(record.variableNames),
|
|
21477
|
-
fileIds: normalizeRefs(record.fileIds)
|
|
21891
|
+
fileIds: normalizeRefs(record.fileIds),
|
|
21892
|
+
sessionArtifactIds: normalizeRefs(record.sessionArtifactIds),
|
|
21893
|
+
actionSuggestions: normalizeActionSuggestions(record.actionSuggestions)
|
|
21478
21894
|
};
|
|
21479
|
-
return show.entryPaths || show.listNames || show.variableNames || show.fileIds ? show : void 0;
|
|
21895
|
+
return show.entryPaths || show.listNames || show.variableNames || show.fileIds || show.sessionArtifactIds || show.actionSuggestions ? show : void 0;
|
|
21896
|
+
}
|
|
21897
|
+
function normalizeActionSuggestions(value) {
|
|
21898
|
+
if (!Array.isArray(value)) return void 0;
|
|
21899
|
+
const suggestions = [];
|
|
21900
|
+
for (const item of value) {
|
|
21901
|
+
const record = asRecord3(item);
|
|
21902
|
+
if (!record) continue;
|
|
21903
|
+
const label = trimString(record.label);
|
|
21904
|
+
if (!label) continue;
|
|
21905
|
+
const suggestionId = trimString(record.suggestionId) || trimString(record.id) || label;
|
|
21906
|
+
suggestions.push({
|
|
21907
|
+
suggestionId,
|
|
21908
|
+
label,
|
|
21909
|
+
...typeof record.description === "string" ? { description: record.description } : {},
|
|
21910
|
+
...asRecord3(record.artifact) ? { artifact: asRecord3(record.artifact) } : {},
|
|
21911
|
+
...asRecord3(record.target) ? { target: asRecord3(record.target) } : {},
|
|
21912
|
+
...asRecord3(record.metadata) ? { metadata: asRecord3(record.metadata) } : {}
|
|
21913
|
+
});
|
|
21914
|
+
}
|
|
21915
|
+
return suggestions.length ? suggestions : void 0;
|
|
21480
21916
|
}
|
|
21481
21917
|
function stringifyTranscriptValue(value, fallback2 = "") {
|
|
21482
21918
|
if (typeof value === "string") {
|
|
@@ -21496,12 +21932,139 @@ function stringifyTranscriptValue(value, fallback2 = "") {
|
|
|
21496
21932
|
return String(value);
|
|
21497
21933
|
}
|
|
21498
21934
|
}
|
|
21499
|
-
function
|
|
21935
|
+
function latestInputEditSummary(metadata) {
|
|
21936
|
+
const lastInputEdit = asRecord3(metadata.lastInputEdit);
|
|
21937
|
+
if (!lastInputEdit) return null;
|
|
21938
|
+
const source = asString(lastInputEdit.source) || "unknown";
|
|
21939
|
+
const actor = asString(lastInputEdit.actorSubjectId) || asString(lastInputEdit.actorPermissionProfileName) || asString(lastInputEdit.jobId) || null;
|
|
21940
|
+
const inputKeys = Array.isArray(lastInputEdit.changedInputKeys) ? lastInputEdit.changedInputKeys.filter(
|
|
21941
|
+
(key) => typeof key === "string" && key.trim().length > 0
|
|
21942
|
+
).slice(0, 6) : [];
|
|
21943
|
+
const relationshipKeys = Array.isArray(lastInputEdit.changedRelationshipKeys) ? lastInputEdit.changedRelationshipKeys.filter(
|
|
21944
|
+
(key) => typeof key === "string" && key.trim().length > 0
|
|
21945
|
+
).slice(0, 6) : [];
|
|
21946
|
+
const changed = [
|
|
21947
|
+
inputKeys.length ? `inputs=${inputKeys.join(",")}` : null,
|
|
21948
|
+
relationshipKeys.length ? `relationships=${relationshipKeys.join(",")}` : null
|
|
21949
|
+
].filter(Boolean);
|
|
21950
|
+
return `lastEdit=${source}${actor ? ` by ${actor}` : ""}${changed.length ? ` (${changed.join("; ")})` : ""}`;
|
|
21951
|
+
}
|
|
21952
|
+
function artifactIssueSummary(record) {
|
|
21953
|
+
const validation = asRecord3(record.validation);
|
|
21954
|
+
if (!validation) return null;
|
|
21955
|
+
const issues = Array.isArray(validation.issues) ? validation.issues.map((issue) => asRecord3(issue)).filter((issue) => Boolean(issue)).slice(0, 3) : [];
|
|
21956
|
+
if (issues.length > 0) {
|
|
21957
|
+
return `issues=${issues.map((issue) => {
|
|
21958
|
+
const code = asString(issue.code) || asString(issue.kind) || "issue";
|
|
21959
|
+
const path7 = asString(issue.path);
|
|
21960
|
+
const message = trimString(issue.message);
|
|
21961
|
+
return `${code}${path7 ? ` at ${path7}` : ""}${message ? ` (${message})` : ""}`;
|
|
21962
|
+
}).join("; ")}`;
|
|
21963
|
+
}
|
|
21964
|
+
const error2 = trimString(validation.error) || trimString(validation.reason) || trimString(validation.message);
|
|
21965
|
+
return error2 ? `validation=${error2}` : null;
|
|
21966
|
+
}
|
|
21967
|
+
function artifactExecutionSummary(metadata) {
|
|
21968
|
+
const execution = asRecord3(metadata.execution);
|
|
21969
|
+
if (!execution) return null;
|
|
21970
|
+
const result = asRecord3(execution.result);
|
|
21971
|
+
const awaiting = asString(result?.awaiting) || asString(execution.awaiting);
|
|
21972
|
+
const pendingTransition = asString(result?.pendingTransition) || asString(execution.pendingTransition);
|
|
21973
|
+
const approval = asRecord3(result?.approval) || asRecord3(execution.approval);
|
|
21974
|
+
const approvalTarget = asString(approval?.permissionProfileName) || asString(approval?.permissionProfileId) || asString(approval?.assigneeSubjectId);
|
|
21975
|
+
const error2 = trimString(execution.error);
|
|
21976
|
+
const pieces = [
|
|
21977
|
+
awaiting ? `awaiting=${awaiting}` : null,
|
|
21978
|
+
pendingTransition ? `pendingTransition=${pendingTransition}` : null,
|
|
21979
|
+
approvalTarget ? `approvalTarget=${approvalTarget}` : null,
|
|
21980
|
+
error2 ? `executionError=${error2}` : null
|
|
21981
|
+
].filter(Boolean);
|
|
21982
|
+
return pieces.length ? pieces.join("; ") : null;
|
|
21983
|
+
}
|
|
21984
|
+
function artifactStatePathSummary(metadata) {
|
|
21985
|
+
const statePlan = asRecord3(metadata.statePlan);
|
|
21986
|
+
if (!statePlan) return null;
|
|
21987
|
+
const machineName = asString(statePlan.machineName);
|
|
21988
|
+
const targetState = asString(statePlan.targetState);
|
|
21989
|
+
const objectPath = asString(statePlan.objectPath);
|
|
21990
|
+
const approvedTransitions = Array.isArray(statePlan.approvedTransitions) ? statePlan.approvedTransitions.length : 0;
|
|
21991
|
+
const approvalDecisions = Array.isArray(statePlan.approvalDecisions) ? statePlan.approvalDecisions.length : 0;
|
|
21992
|
+
const pieces = [
|
|
21993
|
+
machineName || targetState ? `statePath=${machineName || "state_machine"}${targetState ? ` -> ${targetState}` : ""}` : null,
|
|
21994
|
+
objectPath ? `objectPath=${objectPath}` : null,
|
|
21995
|
+
approvedTransitions ? `approvedTransitions=${approvedTransitions}` : null,
|
|
21996
|
+
approvalDecisions ? `approvalDecisions=${approvalDecisions}` : null
|
|
21997
|
+
].filter(Boolean);
|
|
21998
|
+
return pieces.length ? pieces.join("; ") : null;
|
|
21999
|
+
}
|
|
22000
|
+
function artifactSummaryLine(artifactId, record) {
|
|
22001
|
+
if (!record) return `- ${artifactId}: unavailable in session artifact store`;
|
|
22002
|
+
const label = trimString(record.label) || artifactId;
|
|
22003
|
+
const kind = asString(record.kind) || "artifact";
|
|
22004
|
+
const status = asString(record.status) || "unknown";
|
|
22005
|
+
const createdByJobId = asString(record.createdByJobId);
|
|
22006
|
+
const target = asRecord3(record.target);
|
|
22007
|
+
const metadata = asRecord3(record.metadata) || {};
|
|
22008
|
+
const subArtifactIds = Array.isArray(record.subArtifactIds) ? record.subArtifactIds.filter(
|
|
22009
|
+
(id) => typeof id === "string" && id.trim().length > 0
|
|
22010
|
+
).slice(0, 8) : [];
|
|
22011
|
+
const relationships = compactJson(record.relationships, 220);
|
|
22012
|
+
const pieces = [
|
|
22013
|
+
`kind=${kind}`,
|
|
22014
|
+
`status=${status}`,
|
|
22015
|
+
createdByJobId ? `createdByJob=${createdByJobId}` : null,
|
|
22016
|
+
target ? `target=${asString(target.className) || "record"}:${asString(target.id) || "unknown"}${asString(target.label) ? ` (${asString(target.label)})` : ""}` : null,
|
|
22017
|
+
artifactStatePathSummary(metadata),
|
|
22018
|
+
artifactExecutionSummary(metadata),
|
|
22019
|
+
artifactIssueSummary(record),
|
|
22020
|
+
latestInputEditSummary(metadata),
|
|
22021
|
+
subArtifactIds.length ? `subArtifacts=${subArtifactIds.join(",")}` : null,
|
|
22022
|
+
relationships ? `relationships=${relationships}` : null
|
|
22023
|
+
].filter(Boolean);
|
|
22024
|
+
return `- ${artifactId}: ${label}${pieces.length ? `; ${pieces.join("; ")}` : ""}`;
|
|
22025
|
+
}
|
|
22026
|
+
function buildArtifactHistory(show, artifactsById) {
|
|
21500
22027
|
if (!show) return void 0;
|
|
21501
|
-
|
|
22028
|
+
const artifactIds = show.sessionArtifactIds || [];
|
|
22029
|
+
const actionSuggestions = show.actionSuggestions || [];
|
|
22030
|
+
if (artifactIds.length === 0 && actionSuggestions.length === 0) {
|
|
22031
|
+
return `[Agent message]
|
|
21502
22032
|
${stringifyTranscriptValue({ show }, "")}`;
|
|
22033
|
+
}
|
|
22034
|
+
const lines = artifactIds.slice(0, 8).map(
|
|
22035
|
+
(artifactId) => artifactSummaryLine(artifactId, artifactsById?.[artifactId])
|
|
22036
|
+
);
|
|
22037
|
+
if (artifactIds.length > 8) {
|
|
22038
|
+
lines.push(`- ${artifactIds.length - 8} more artifacts omitted`);
|
|
22039
|
+
}
|
|
22040
|
+
if (actionSuggestions.length > 0) {
|
|
22041
|
+
if (artifactIds.length > 0) lines.push("[Agent suggested actions]");
|
|
22042
|
+
for (const suggestion of actionSuggestions.slice(0, 8)) {
|
|
22043
|
+
lines.push(
|
|
22044
|
+
`- ${suggestion.label}${suggestion.description ? `; ${suggestion.description}` : ""}`
|
|
22045
|
+
);
|
|
22046
|
+
}
|
|
22047
|
+
if (actionSuggestions.length > 8) {
|
|
22048
|
+
lines.push(`- ${actionSuggestions.length - 8} more suggestions omitted`);
|
|
22049
|
+
}
|
|
22050
|
+
}
|
|
22051
|
+
const otherRefs = {
|
|
22052
|
+
entryPaths: show.entryPaths,
|
|
22053
|
+
listNames: show.listNames,
|
|
22054
|
+
variableNames: show.variableNames,
|
|
22055
|
+
fileIds: show.fileIds
|
|
22056
|
+
};
|
|
22057
|
+
const hasOtherRefs = Object.values(otherRefs).some(
|
|
22058
|
+
(value) => Array.isArray(value) && value.length > 0
|
|
22059
|
+
);
|
|
22060
|
+
const title = artifactIds.length > 0 ? "[Agent displayed session artifacts]" : "[Agent suggested actions]";
|
|
22061
|
+
return [
|
|
22062
|
+
title,
|
|
22063
|
+
...lines,
|
|
22064
|
+
hasOtherRefs ? `Other shown refs: ${stringifyTranscriptValue(otherRefs, "")}` : null
|
|
22065
|
+
].filter(Boolean).join("\n");
|
|
21503
22066
|
}
|
|
21504
|
-
function normalizeConversationMessage(raw) {
|
|
22067
|
+
function normalizeConversationMessage(raw, artifactsById) {
|
|
21505
22068
|
const record = asRecord3(raw);
|
|
21506
22069
|
if (!record) return null;
|
|
21507
22070
|
const role = record.role === "user" ? "user" : record.role === "assistant" ? "assistant" : null;
|
|
@@ -21513,6 +22076,12 @@ function normalizeConversationMessage(raw) {
|
|
|
21513
22076
|
const id = asString(record.id) || crypto.randomUUID();
|
|
21514
22077
|
const timestamp = asNumber(record.timestamp) || asNumber(record.ts) || 0;
|
|
21515
22078
|
if (!content && !show) return null;
|
|
22079
|
+
const artifactHistory = buildArtifactHistory(show, artifactsById);
|
|
22080
|
+
const historyContent = role === "assistant" ? content && artifactHistory ? `[Assistant reply]
|
|
22081
|
+
${content}
|
|
22082
|
+
|
|
22083
|
+
${artifactHistory}` : content ? `[Assistant reply]
|
|
22084
|
+
${content}` : artifactHistory : void 0;
|
|
21516
22085
|
return {
|
|
21517
22086
|
id,
|
|
21518
22087
|
role,
|
|
@@ -21521,8 +22090,7 @@ function normalizeConversationMessage(raw) {
|
|
|
21521
22090
|
jobId: asString(record.jobId),
|
|
21522
22091
|
promptId: asString(record.promptId),
|
|
21523
22092
|
show,
|
|
21524
|
-
historyContent
|
|
21525
|
-
${content}` : buildArtifactHistory(show) : void 0,
|
|
22093
|
+
historyContent,
|
|
21526
22094
|
source: "conversation"
|
|
21527
22095
|
};
|
|
21528
22096
|
}
|
|
@@ -21565,7 +22133,7 @@ ${assistantContent}`,
|
|
|
21565
22133
|
return entries;
|
|
21566
22134
|
});
|
|
21567
22135
|
}
|
|
21568
|
-
function normalizeAgentMessageEntries(jobId, rawMessages) {
|
|
22136
|
+
function normalizeAgentMessageEntries(jobId, rawMessages, artifactsById) {
|
|
21569
22137
|
return asArray(rawMessages).map((value) => asRecord3(value)).filter((value) => Boolean(value)).sort(
|
|
21570
22138
|
(left, right) => (asNumber(left.timestamp) || asNumber(left.ts) || 0) - (asNumber(right.timestamp) || asNumber(right.ts) || 0)
|
|
21571
22139
|
).flatMap((message) => {
|
|
@@ -21596,14 +22164,14 @@ ${reply}`,
|
|
|
21596
22164
|
timestamp,
|
|
21597
22165
|
jobId,
|
|
21598
22166
|
show,
|
|
21599
|
-
historyContent: buildArtifactHistory(show),
|
|
22167
|
+
historyContent: buildArtifactHistory(show, artifactsById),
|
|
21600
22168
|
source: "job_agent_message"
|
|
21601
22169
|
});
|
|
21602
22170
|
}
|
|
21603
22171
|
return entries;
|
|
21604
22172
|
});
|
|
21605
22173
|
}
|
|
21606
|
-
function buildJobFallbackEntries(jobId, job2, sessionHeap) {
|
|
22174
|
+
function buildJobFallbackEntries(jobId, job2, sessionHeap, artifactsById) {
|
|
21607
22175
|
const timestamp = asNumber(job2.finishedAt) || asNumber(job2.startedAt) || asNumber(job2.submittedAt) || 0;
|
|
21608
22176
|
const resultPreview = stringifyTranscriptValue(
|
|
21609
22177
|
job2.result,
|
|
@@ -21641,7 +22209,7 @@ ${responseText}`,
|
|
|
21641
22209
|
timestamp,
|
|
21642
22210
|
jobId,
|
|
21643
22211
|
show,
|
|
21644
|
-
historyContent: buildArtifactHistory(show),
|
|
22212
|
+
historyContent: buildArtifactHistory(show, artifactsById),
|
|
21645
22213
|
source: "job_result"
|
|
21646
22214
|
});
|
|
21647
22215
|
}
|
|
@@ -21695,10 +22263,11 @@ function buildJobCodeEntry(jobId, job2) {
|
|
|
21695
22263
|
function buildSessionTranscript(input) {
|
|
21696
22264
|
const liveDoc = input.liveDoc || null;
|
|
21697
22265
|
const sessionHeap = input.sessionHeap || EMPTY_HEAP;
|
|
22266
|
+
const artifactsById = artifactRecordsById(liveDoc);
|
|
21698
22267
|
const transcript = [];
|
|
21699
22268
|
const conversationMessages = asArray(
|
|
21700
22269
|
asRecord3(liveDoc?.conversation)?.messages
|
|
21701
|
-
).map((message) => normalizeConversationMessage(message)).filter((message) => Boolean(message));
|
|
22270
|
+
).map((message) => normalizeConversationMessage(message, artifactsById)).filter((message) => Boolean(message));
|
|
21702
22271
|
const conversationPromptIds = new Set(
|
|
21703
22272
|
conversationMessages.map((message) => message.promptId).filter((promptId) => Boolean(promptId))
|
|
21704
22273
|
);
|
|
@@ -21725,7 +22294,8 @@ function buildSessionTranscript(input) {
|
|
|
21725
22294
|
if (!assistantConversationJobIds.has(jobId)) {
|
|
21726
22295
|
const agentEntries = normalizeAgentMessageEntries(
|
|
21727
22296
|
jobId,
|
|
21728
|
-
job2.agentMessages
|
|
22297
|
+
job2.agentMessages,
|
|
22298
|
+
artifactsById
|
|
21729
22299
|
);
|
|
21730
22300
|
if (agentEntries.length > 0) {
|
|
21731
22301
|
transcript.push(...agentEntries);
|
|
@@ -21734,7 +22304,8 @@ function buildSessionTranscript(input) {
|
|
|
21734
22304
|
...buildJobFallbackEntries(
|
|
21735
22305
|
jobId,
|
|
21736
22306
|
job2,
|
|
21737
|
-
sessionHeap
|
|
22307
|
+
sessionHeap,
|
|
22308
|
+
artifactsById
|
|
21738
22309
|
)
|
|
21739
22310
|
);
|
|
21740
22311
|
}
|
|
@@ -21982,15 +22553,50 @@ function toRecordSearchResult(className, node) {
|
|
|
21982
22553
|
return [];
|
|
21983
22554
|
}
|
|
21984
22555
|
) : [];
|
|
22556
|
+
const graphPathId = extractRecordIdFromGraphPath(path7, className);
|
|
22557
|
+
const realIdField = fields.find(
|
|
22558
|
+
(field) => normalizeGraphPathSegment(field.name) === "real_id" && typeof field.value === "string" && field.value.trim()
|
|
22559
|
+
);
|
|
22560
|
+
const id = typeof realIdField?.value === "string" ? realIdField.value.trim() : graphPathId;
|
|
22561
|
+
const rawLabel = typeof node.label === "string" && node.label.trim() ? node.label : "";
|
|
22562
|
+
if (fields.length === 0 && rawLabel && isPlaceholderRecordLabel(rawLabel, graphPathId, path7)) {
|
|
22563
|
+
return null;
|
|
22564
|
+
}
|
|
22565
|
+
const fallbackLabel = displayLabelFromFields(fields);
|
|
22566
|
+
const label = rawLabel && !isPlaceholderRecordLabel(rawLabel, id, path7) ? rawLabel : fallbackLabel || rawLabel || id;
|
|
21985
22567
|
return {
|
|
21986
22568
|
path: path7,
|
|
21987
22569
|
className,
|
|
21988
|
-
id
|
|
21989
|
-
label
|
|
22570
|
+
id,
|
|
22571
|
+
label,
|
|
21990
22572
|
description: typeof node.description === "string" && node.description.trim() ? node.description : null,
|
|
21991
22573
|
fields
|
|
21992
22574
|
};
|
|
21993
22575
|
}
|
|
22576
|
+
function isPlaceholderRecordLabel(label, id, path7) {
|
|
22577
|
+
const normalizedLabel = normalizeGraphPathSegment(label);
|
|
22578
|
+
return normalizedLabel === normalizeGraphPathSegment(id) || normalizedLabel === normalizeGraphPathSegment(path7);
|
|
22579
|
+
}
|
|
22580
|
+
function displayLabelFromFields(fields) {
|
|
22581
|
+
const preferredFieldNames = [
|
|
22582
|
+
"name",
|
|
22583
|
+
"title",
|
|
22584
|
+
"label",
|
|
22585
|
+
"display_name",
|
|
22586
|
+
"file_name",
|
|
22587
|
+
"number",
|
|
22588
|
+
"code"
|
|
22589
|
+
];
|
|
22590
|
+
for (const preferred of preferredFieldNames) {
|
|
22591
|
+
const match = fields.find(
|
|
22592
|
+
(field) => normalizeGraphPathSegment(field.name) === preferred && typeof field.value === "string" && field.value.trim()
|
|
22593
|
+
);
|
|
22594
|
+
if (typeof match?.value === "string") {
|
|
22595
|
+
return match.value.trim();
|
|
22596
|
+
}
|
|
22597
|
+
}
|
|
22598
|
+
return null;
|
|
22599
|
+
}
|
|
21994
22600
|
function normalizeRecordSearchText(value) {
|
|
21995
22601
|
return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, " ").replace(/\s+/g, " ").trim();
|
|
21996
22602
|
}
|
|
@@ -22239,6 +22845,26 @@ var STANDARD_MODULES_OPERATIONS = [
|
|
|
22239
22845
|
var BUILTIN_MODULES = {
|
|
22240
22846
|
standard_modules: STANDARD_MODULES_OPERATIONS
|
|
22241
22847
|
};
|
|
22848
|
+
function stateNameFromMethodName(methodName) {
|
|
22849
|
+
const raw = methodName.startsWith("to") ? methodName.slice(2) : methodName;
|
|
22850
|
+
return raw.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^A-Za-z0-9]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
22851
|
+
}
|
|
22852
|
+
function appendQueryOptions(searchParams, query) {
|
|
22853
|
+
for (const [key, value] of Object.entries(query || {})) {
|
|
22854
|
+
if (value === null || typeof value === "undefined" || value === "") {
|
|
22855
|
+
continue;
|
|
22856
|
+
}
|
|
22857
|
+
if (value instanceof Date) {
|
|
22858
|
+
searchParams.set(key, value.toISOString());
|
|
22859
|
+
continue;
|
|
22860
|
+
}
|
|
22861
|
+
if (Array.isArray(value)) {
|
|
22862
|
+
if (value.length > 0) searchParams.set(key, value.join(","));
|
|
22863
|
+
continue;
|
|
22864
|
+
}
|
|
22865
|
+
searchParams.set(key, String(value));
|
|
22866
|
+
}
|
|
22867
|
+
}
|
|
22242
22868
|
var DEFAULT_DIRECT_RECORD_OBJECTS_REQUEST_BATCH_SIZE = 100;
|
|
22243
22869
|
var MAX_RECORD_OBJECTS_CONCURRENCY = 16;
|
|
22244
22870
|
var DEFAULT_DIRECT_RECORD_OBJECTS_RETRY_COUNT = 3;
|
|
@@ -22269,8 +22895,20 @@ function bodyInitFromSessionFileUpload(body) {
|
|
|
22269
22895
|
return body;
|
|
22270
22896
|
}
|
|
22271
22897
|
var EFFECT_CATALOG_SYNC_TIMEOUT_MS = 12e4;
|
|
22898
|
+
var EFFECT_CATALOG_SYNC_BATCH_SIZE = 20;
|
|
22272
22899
|
var EFFECT_CATALOG_SYNC_RETRY_COUNT = 3;
|
|
22273
22900
|
var EFFECT_CATALOG_SYNC_RETRY_DELAY_MS = 1e3;
|
|
22901
|
+
function chunkItems(items, batchSize) {
|
|
22902
|
+
const chunks = [];
|
|
22903
|
+
for (let offset = 0; offset < items.length; offset += batchSize) {
|
|
22904
|
+
chunks.push(items.slice(offset, offset + batchSize));
|
|
22905
|
+
}
|
|
22906
|
+
return chunks;
|
|
22907
|
+
}
|
|
22908
|
+
function isUnsupportedEffectCatalogMutation(error2) {
|
|
22909
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
22910
|
+
return message.includes("Unknown RPC method: effects.resetCatalog") || message.includes("Unknown RPC method: effects.addCatalog") || message.includes("Method not found: effects.resetCatalog") || message.includes("Method not found: effects.addCatalog");
|
|
22911
|
+
}
|
|
22274
22912
|
function planRecordObjectsChunks(records, batchSize) {
|
|
22275
22913
|
const total = records.length;
|
|
22276
22914
|
const size = Math.max(1, Math.min(batchSize, total));
|
|
@@ -22282,6 +22920,23 @@ function planRecordObjectsChunks(records, batchSize) {
|
|
|
22282
22920
|
}
|
|
22283
22921
|
return plans;
|
|
22284
22922
|
}
|
|
22923
|
+
function preserveRecordObjectRealId(record) {
|
|
22924
|
+
const realId = record.id.trim();
|
|
22925
|
+
if (!realId) {
|
|
22926
|
+
return record;
|
|
22927
|
+
}
|
|
22928
|
+
const fields = record.fields || {};
|
|
22929
|
+
if (typeof fields.real_id === "string" && fields.real_id.trim()) {
|
|
22930
|
+
return record;
|
|
22931
|
+
}
|
|
22932
|
+
return {
|
|
22933
|
+
...record,
|
|
22934
|
+
fields: {
|
|
22935
|
+
...fields,
|
|
22936
|
+
real_id: realId
|
|
22937
|
+
}
|
|
22938
|
+
};
|
|
22939
|
+
}
|
|
22285
22940
|
function computeEffectKey2(effect) {
|
|
22286
22941
|
const attachedClass = effect.className?.trim();
|
|
22287
22942
|
if (!attachedClass) {
|
|
@@ -22519,11 +23174,105 @@ var Environment = class _Environment {
|
|
|
22519
23174
|
getAwaitingCount: async () => this.getAwaitingRecordCount()
|
|
22520
23175
|
};
|
|
22521
23176
|
}
|
|
23177
|
+
/**
|
|
23178
|
+
* Mirror product-owned workflow state into Granular without making Granular
|
|
23179
|
+
* own the customer application's state machine.
|
|
23180
|
+
*/
|
|
23181
|
+
async recordState(input) {
|
|
23182
|
+
const { machine, state, ...target } = input;
|
|
23183
|
+
if (!machine.trim()) {
|
|
23184
|
+
throw new Error("State update requires a machine name");
|
|
23185
|
+
}
|
|
23186
|
+
if (!state.trim()) {
|
|
23187
|
+
throw new Error("State update requires a state");
|
|
23188
|
+
}
|
|
23189
|
+
return this.recordObject({
|
|
23190
|
+
className: target.className,
|
|
23191
|
+
id: target.id,
|
|
23192
|
+
...target.label ? { label: target.label } : {},
|
|
23193
|
+
...target.fields ? { fields: target.fields } : {},
|
|
23194
|
+
...target.relationships ? { relationships: target.relationships } : {},
|
|
23195
|
+
states: {
|
|
23196
|
+
[machine.trim()]: {
|
|
23197
|
+
state: state.trim(),
|
|
23198
|
+
...target.source ? { source: target.source } : {},
|
|
23199
|
+
...target.cause ? { cause: target.cause } : {},
|
|
23200
|
+
...target.actorId ? { actorId: target.actorId } : {},
|
|
23201
|
+
...target.observedAt !== void 0 ? { observedAt: target.observedAt } : {},
|
|
23202
|
+
...target.force !== void 0 ? { force: target.force } : {},
|
|
23203
|
+
...target.metadata ? { metadata: target.metadata } : {}
|
|
23204
|
+
}
|
|
23205
|
+
}
|
|
23206
|
+
});
|
|
23207
|
+
}
|
|
23208
|
+
/**
|
|
23209
|
+
* Mirror product-owned workflow state into Granular without making Granular
|
|
23210
|
+
* own the customer application's state machine.
|
|
23211
|
+
*
|
|
23212
|
+
* Example:
|
|
23213
|
+
* `await env.recordState({ className: "spend_request", id, machine: "lifecycle", state: "policy_review", source: "customer_backend" })`
|
|
23214
|
+
*/
|
|
23215
|
+
state(target) {
|
|
23216
|
+
const observe = async (machineName, stateName, input = {}) => {
|
|
23217
|
+
const observedState = input.observedState || input.state || stateName;
|
|
23218
|
+
if (!observedState) {
|
|
23219
|
+
throw new Error("State observation requires a target state");
|
|
23220
|
+
}
|
|
23221
|
+
return this.recordState({
|
|
23222
|
+
...target,
|
|
23223
|
+
machine: machineName,
|
|
23224
|
+
state: observedState,
|
|
23225
|
+
...input.source ? { source: input.source } : {},
|
|
23226
|
+
...input.cause ? { cause: input.cause } : {},
|
|
23227
|
+
...input.actorId ? { actorId: input.actorId } : {},
|
|
23228
|
+
...input.observedAt !== void 0 ? { observedAt: input.observedAt } : {},
|
|
23229
|
+
...input.force !== void 0 ? { force: input.force } : {},
|
|
23230
|
+
...input.metadata ? { metadata: input.metadata } : {}
|
|
23231
|
+
});
|
|
23232
|
+
};
|
|
23233
|
+
return new Proxy(
|
|
23234
|
+
{},
|
|
23235
|
+
{
|
|
23236
|
+
get: (_target, machineProperty) => {
|
|
23237
|
+
if (typeof machineProperty !== "string") return void 0;
|
|
23238
|
+
return new Proxy(
|
|
23239
|
+
{},
|
|
23240
|
+
{
|
|
23241
|
+
get: (_machineTarget, stateProperty) => {
|
|
23242
|
+
if (stateProperty === "to") {
|
|
23243
|
+
return (stateName, input) => observe(machineProperty, stateName, input || {});
|
|
23244
|
+
}
|
|
23245
|
+
if (typeof stateProperty !== "string") return void 0;
|
|
23246
|
+
return (input) => observe(
|
|
23247
|
+
machineProperty,
|
|
23248
|
+
stateNameFromMethodName(stateProperty),
|
|
23249
|
+
input || {}
|
|
23250
|
+
);
|
|
23251
|
+
}
|
|
23252
|
+
}
|
|
23253
|
+
);
|
|
23254
|
+
}
|
|
23255
|
+
}
|
|
23256
|
+
);
|
|
23257
|
+
}
|
|
22522
23258
|
get feedback() {
|
|
22523
23259
|
return {
|
|
22524
23260
|
list: async () => this.listFeedback()
|
|
22525
23261
|
};
|
|
22526
23262
|
}
|
|
23263
|
+
get manualActions() {
|
|
23264
|
+
return {
|
|
23265
|
+
record: (input) => this.recordManualAction(input),
|
|
23266
|
+
list: (options = {}) => this.listManualActions(options),
|
|
23267
|
+
suggest: (options = {}) => this.suggestManualActions(options)
|
|
23268
|
+
};
|
|
23269
|
+
}
|
|
23270
|
+
get artifactApprovals() {
|
|
23271
|
+
return {
|
|
23272
|
+
list: (options = {}) => this.listArtifactApprovals(options),
|
|
23273
|
+
decide: (approvalTaskId, input) => this.decideArtifactApproval(approvalTaskId, input)
|
|
23274
|
+
};
|
|
23275
|
+
}
|
|
22527
23276
|
/**
|
|
22528
23277
|
* Sessionless environments do not own a live transport, so disconnecting the
|
|
22529
23278
|
* environment handle itself is a no-op. This keeps the public surface
|
|
@@ -22602,6 +23351,50 @@ var Environment = class _Environment {
|
|
|
22602
23351
|
const response = await this.controlPlaneRequest(`/control/environments/${this.environmentId}/feedback`);
|
|
22603
23352
|
return Array.isArray(response.items) ? response.items : [];
|
|
22604
23353
|
}
|
|
23354
|
+
async recordManualAction(input) {
|
|
23355
|
+
const body = {
|
|
23356
|
+
...input,
|
|
23357
|
+
...input.idempotencyKey ? { idempotencyKey: input.idempotencyKey } : {}
|
|
23358
|
+
};
|
|
23359
|
+
return this.controlPlaneRequest(
|
|
23360
|
+
`/control/environments/${this.environmentId}/manual-actions`,
|
|
23361
|
+
{
|
|
23362
|
+
method: "POST",
|
|
23363
|
+
body: JSON.stringify(body)
|
|
23364
|
+
}
|
|
23365
|
+
);
|
|
23366
|
+
}
|
|
23367
|
+
async listManualActions(options = {}) {
|
|
23368
|
+
const query = new URLSearchParams();
|
|
23369
|
+
appendQueryOptions(query, options);
|
|
23370
|
+
const suffix = query.toString() ? `?${query.toString()}` : "";
|
|
23371
|
+
return this.controlPlaneRequest(`/control/environments/${this.environmentId}/manual-actions${suffix}`);
|
|
23372
|
+
}
|
|
23373
|
+
async suggestManualActions(options = {}) {
|
|
23374
|
+
const query = new URLSearchParams();
|
|
23375
|
+
appendQueryOptions(query, options);
|
|
23376
|
+
const suffix = query.toString() ? `?${query.toString()}` : "";
|
|
23377
|
+
return this.controlPlaneRequest(
|
|
23378
|
+
`/control/environments/${this.environmentId}/manual-actions/suggestions${suffix}`
|
|
23379
|
+
);
|
|
23380
|
+
}
|
|
23381
|
+
async listArtifactApprovals(options = {}) {
|
|
23382
|
+
const query = new URLSearchParams();
|
|
23383
|
+
appendQueryOptions(query, options);
|
|
23384
|
+
const suffix = query.toString() ? `?${query.toString()}` : "";
|
|
23385
|
+
return this.controlPlaneRequest(
|
|
23386
|
+
`/control/environments/${this.environmentId}/artifact-approvals${suffix}`
|
|
23387
|
+
);
|
|
23388
|
+
}
|
|
23389
|
+
async decideArtifactApproval(approvalTaskId, input) {
|
|
23390
|
+
return this.controlPlaneRequest(
|
|
23391
|
+
`/control/environments/${this.environmentId}/artifact-approvals/${encodeURIComponent(approvalTaskId)}/decide`,
|
|
23392
|
+
{
|
|
23393
|
+
method: "POST",
|
|
23394
|
+
body: JSON.stringify(input)
|
|
23395
|
+
}
|
|
23396
|
+
);
|
|
23397
|
+
}
|
|
22605
23398
|
getRuntimeBaseUrl() {
|
|
22606
23399
|
return deriveRuntimeBaseUrl(this._apiEndpoint);
|
|
22607
23400
|
}
|
|
@@ -23426,10 +24219,11 @@ var Environment = class _Environment {
|
|
|
23426
24219
|
if (!Array.isArray(records) || records.length === 0) {
|
|
23427
24220
|
return [];
|
|
23428
24221
|
}
|
|
24222
|
+
const recordsToWrite = records.map(preserveRecordObjectRealId);
|
|
23429
24223
|
const batchSize = Math.max(
|
|
23430
24224
|
1,
|
|
23431
24225
|
Math.min(
|
|
23432
|
-
|
|
24226
|
+
recordsToWrite.length,
|
|
23433
24227
|
options?.batchSize ?? DEFAULT_DIRECT_RECORD_OBJECTS_REQUEST_BATCH_SIZE
|
|
23434
24228
|
)
|
|
23435
24229
|
);
|
|
@@ -23437,8 +24231,8 @@ var Environment = class _Environment {
|
|
|
23437
24231
|
MAX_RECORD_OBJECTS_CONCURRENCY,
|
|
23438
24232
|
Math.max(1, options?.concurrency ?? 1)
|
|
23439
24233
|
);
|
|
23440
|
-
const plans = planRecordObjectsChunks(
|
|
23441
|
-
const total =
|
|
24234
|
+
const plans = planRecordObjectsChunks(recordsToWrite, batchSize);
|
|
24235
|
+
const total = recordsToWrite.length;
|
|
23442
24236
|
const results = new Array(total);
|
|
23443
24237
|
const onChunk = options?.onChunkComplete;
|
|
23444
24238
|
for (let waveStart = 0; waveStart < plans.length; waveStart += concurrency) {
|
|
@@ -23509,12 +24303,13 @@ var Environment = class _Environment {
|
|
|
23509
24303
|
* synchronous upserts and fine-grained chunk progress via **`onChunkComplete`**.
|
|
23510
24304
|
*/
|
|
23511
24305
|
async enqueueRecordImport(records, options = {}) {
|
|
24306
|
+
const recordsToImport = records.map(preserveRecordObjectRealId);
|
|
23512
24307
|
return this.controlPlaneRequest(
|
|
23513
24308
|
`/control/environments/${this.environmentId}/record-imports`,
|
|
23514
24309
|
{
|
|
23515
24310
|
method: "POST",
|
|
23516
24311
|
body: JSON.stringify({
|
|
23517
|
-
records,
|
|
24312
|
+
records: recordsToImport,
|
|
23518
24313
|
batchSize: options.batchSize,
|
|
23519
24314
|
setupRunId: options.setupRunId,
|
|
23520
24315
|
writeMode: options.writeMode
|
|
@@ -23622,11 +24417,7 @@ var EnvironmentSession = class extends Session {
|
|
|
23622
24417
|
}
|
|
23623
24418
|
buildSessionDataUrl(path7, query) {
|
|
23624
24419
|
const searchParams = new URLSearchParams();
|
|
23625
|
-
|
|
23626
|
-
if (value !== null && typeof value !== "undefined" && value !== "") {
|
|
23627
|
-
searchParams.set(key, String(value));
|
|
23628
|
-
}
|
|
23629
|
-
}
|
|
24420
|
+
appendQueryOptions(searchParams, query);
|
|
23630
24421
|
const queryString = searchParams.toString();
|
|
23631
24422
|
return `${this.environment.runtimeBaseUrl}${this.sessionDataRoutePrefix}/${encodeURIComponent(this.sessionId)}${path7}${queryString ? `?${queryString}` : ""}`;
|
|
23632
24423
|
}
|
|
@@ -23709,9 +24500,108 @@ var EnvironmentSession = class extends Session {
|
|
|
23709
24500
|
),
|
|
23710
24501
|
get: (jobId) => this.sessionDataRequest(
|
|
23711
24502
|
`/jobs/${encodeURIComponent(jobId)}`
|
|
24503
|
+
),
|
|
24504
|
+
latest: async (options = {}) => {
|
|
24505
|
+
const page = await this.sessionDataRequest("/jobs", {
|
|
24506
|
+
status: options.status || "all",
|
|
24507
|
+
latest: true,
|
|
24508
|
+
limit: 1
|
|
24509
|
+
});
|
|
24510
|
+
return page.items[0] || null;
|
|
24511
|
+
}
|
|
24512
|
+
};
|
|
24513
|
+
}
|
|
24514
|
+
get artifacts() {
|
|
24515
|
+
return {
|
|
24516
|
+
list: (options = {}) => {
|
|
24517
|
+
const queryOptions = { ...options };
|
|
24518
|
+
if (options.target) {
|
|
24519
|
+
queryOptions.targetClassName = options.target.className;
|
|
24520
|
+
queryOptions.targetId = options.target.id;
|
|
24521
|
+
delete queryOptions.target;
|
|
24522
|
+
}
|
|
24523
|
+
return this.sessionDataRequest("/artifacts", queryOptions);
|
|
24524
|
+
},
|
|
24525
|
+
listForLatestJob: (options = {}) => this.artifacts.list({
|
|
24526
|
+
...options,
|
|
24527
|
+
latestJob: true
|
|
24528
|
+
}),
|
|
24529
|
+
get: (artifactId) => this.sessionDataRequest(
|
|
24530
|
+
`/artifacts/${encodeURIComponent(artifactId)}`
|
|
24531
|
+
),
|
|
24532
|
+
create: (artifact) => this.sessionDataRequest(
|
|
24533
|
+
"/artifacts",
|
|
24534
|
+
void 0,
|
|
24535
|
+
{
|
|
24536
|
+
method: "POST",
|
|
24537
|
+
body: artifact
|
|
24538
|
+
}
|
|
24539
|
+
),
|
|
24540
|
+
updateInputs: (artifactId, patch) => this.sessionDataRequest(
|
|
24541
|
+
`/artifacts/${encodeURIComponent(artifactId)}`,
|
|
24542
|
+
void 0,
|
|
24543
|
+
{
|
|
24544
|
+
method: "PATCH",
|
|
24545
|
+
body: patch
|
|
24546
|
+
}
|
|
24547
|
+
),
|
|
24548
|
+
validate: (artifactId) => this.sessionDataRequest(
|
|
24549
|
+
`/artifacts/${encodeURIComponent(artifactId)}/validate`,
|
|
24550
|
+
void 0,
|
|
24551
|
+
{ method: "POST" }
|
|
24552
|
+
),
|
|
24553
|
+
execute: (artifactId, options) => this.sessionDataRequest(
|
|
24554
|
+
`/artifacts/${encodeURIComponent(artifactId)}/execute`,
|
|
24555
|
+
void 0,
|
|
24556
|
+
{ method: "POST", body: options }
|
|
24557
|
+
),
|
|
24558
|
+
approve: (artifactId, options) => this.sessionDataRequest(
|
|
24559
|
+
`/artifacts/${encodeURIComponent(artifactId)}/approve`,
|
|
24560
|
+
void 0,
|
|
24561
|
+
{ method: "POST", body: options }
|
|
24562
|
+
),
|
|
24563
|
+
cancel: (artifactId) => this.sessionDataRequest(
|
|
24564
|
+
`/artifacts/${encodeURIComponent(artifactId)}/cancel`,
|
|
24565
|
+
void 0,
|
|
24566
|
+
{ method: "POST" }
|
|
23712
24567
|
)
|
|
23713
24568
|
};
|
|
23714
24569
|
}
|
|
24570
|
+
get manualActions() {
|
|
24571
|
+
const useDelegatedBrowserRoute = this.sessionDataRoutePrefix === "/sdk/browser-sessions";
|
|
24572
|
+
return {
|
|
24573
|
+
record: (input) => useDelegatedBrowserRoute ? this.sessionDataRequest(
|
|
24574
|
+
"/manual-actions",
|
|
24575
|
+
void 0,
|
|
24576
|
+
{
|
|
24577
|
+
method: "POST",
|
|
24578
|
+
body: { ...input, sessionId: this.sessionId }
|
|
24579
|
+
}
|
|
24580
|
+
) : this.environment.manualActions.record({
|
|
24581
|
+
...input,
|
|
24582
|
+
sessionId: this.sessionId
|
|
24583
|
+
}),
|
|
24584
|
+
list: (options = {}) => useDelegatedBrowserRoute ? this.sessionDataRequest("/manual-actions", { ...options, sessionId: this.sessionId }) : this.environment.manualActions.list({
|
|
24585
|
+
...options,
|
|
24586
|
+
sessionId: this.sessionId
|
|
24587
|
+
}),
|
|
24588
|
+
suggest: (options = {}) => useDelegatedBrowserRoute ? this.sessionDataRequest(
|
|
24589
|
+
"/manual-actions/suggestions",
|
|
24590
|
+
options
|
|
24591
|
+
) : this.environment.manualActions.suggest(options)
|
|
24592
|
+
};
|
|
24593
|
+
}
|
|
24594
|
+
get artifactApprovals() {
|
|
24595
|
+
const useDelegatedBrowserRoute = this.sessionDataRoutePrefix === "/sdk/browser-sessions";
|
|
24596
|
+
return {
|
|
24597
|
+
list: (options = {}) => useDelegatedBrowserRoute ? this.sessionDataRequest("/artifact-approvals", options) : this.environment.artifactApprovals.list(options),
|
|
24598
|
+
decide: (approvalTaskId, input) => useDelegatedBrowserRoute ? this.sessionDataRequest(
|
|
24599
|
+
`/artifact-approvals/${encodeURIComponent(approvalTaskId)}/decide`,
|
|
24600
|
+
void 0,
|
|
24601
|
+
{ method: "POST", body: input }
|
|
24602
|
+
) : this.environment.artifactApprovals.decide(approvalTaskId, input)
|
|
24603
|
+
};
|
|
24604
|
+
}
|
|
23715
24605
|
get files() {
|
|
23716
24606
|
return {
|
|
23717
24607
|
list: (options = {}) => this.sessionDataRequest(
|
|
@@ -23792,13 +24682,16 @@ var EnvironmentSession = class extends Session {
|
|
|
23792
24682
|
get transcript() {
|
|
23793
24683
|
return {
|
|
23794
24684
|
list: async (options = {}) => {
|
|
23795
|
-
const [messages, jobs, entries, lists] = await Promise.all([
|
|
24685
|
+
const [messages, jobs, entries, lists, artifacts] = await Promise.all([
|
|
23796
24686
|
this.collectAllSessionItems(this.messages.list),
|
|
23797
24687
|
this.collectAllSessionItems(
|
|
23798
24688
|
(pageOptions) => this.jobs.list({ ...pageOptions, status: "all" })
|
|
23799
24689
|
),
|
|
23800
24690
|
this.collectAllSessionItems(this.heap.entries.list),
|
|
23801
|
-
this.collectAllSessionItems(this.heap.lists.list)
|
|
24691
|
+
this.collectAllSessionItems(this.heap.lists.list),
|
|
24692
|
+
this.collectAllSessionItems(
|
|
24693
|
+
(pageOptions) => this.artifacts.list({ ...pageOptions, status: "all" })
|
|
24694
|
+
)
|
|
23802
24695
|
]);
|
|
23803
24696
|
const liveDoc = {
|
|
23804
24697
|
conversation: { messages },
|
|
@@ -23812,6 +24705,21 @@ var EnvironmentSession = class extends Session {
|
|
|
23812
24705
|
(entry) => Boolean(entry)
|
|
23813
24706
|
)
|
|
23814
24707
|
)
|
|
24708
|
+
},
|
|
24709
|
+
artifacts: {
|
|
24710
|
+
byId: Object.fromEntries(
|
|
24711
|
+
artifacts.map((artifact) => {
|
|
24712
|
+
return artifact?.artifactId ? [
|
|
24713
|
+
artifact.artifactId,
|
|
24714
|
+
artifact
|
|
24715
|
+
] : null;
|
|
24716
|
+
}).filter(
|
|
24717
|
+
(entry) => Boolean(entry)
|
|
24718
|
+
)
|
|
24719
|
+
),
|
|
24720
|
+
order: artifacts.map((artifact) => artifact?.artifactId).filter(
|
|
24721
|
+
(artifactId) => Boolean(artifactId)
|
|
24722
|
+
)
|
|
23815
24723
|
}
|
|
23816
24724
|
};
|
|
23817
24725
|
const heap = normalizeHeapSnapshot({
|
|
@@ -23888,6 +24796,12 @@ var EnvironmentSession = class extends Session {
|
|
|
23888
24796
|
async recordObject(options) {
|
|
23889
24797
|
return this.environment.recordObject(options);
|
|
23890
24798
|
}
|
|
24799
|
+
async recordState(input) {
|
|
24800
|
+
return this.environment.recordState(input);
|
|
24801
|
+
}
|
|
24802
|
+
state(target) {
|
|
24803
|
+
return this.environment.state(target);
|
|
24804
|
+
}
|
|
23891
24805
|
async recordObjects(records, options) {
|
|
23892
24806
|
return this.environment.recordObjects(records, options);
|
|
23893
24807
|
}
|
|
@@ -24715,15 +25629,43 @@ var Granular = class _Granular {
|
|
|
24715
25629
|
const effects2 = Array.from(
|
|
24716
25630
|
this.getSandboxEffectMap(host.sandboxId).values()
|
|
24717
25631
|
).map((effect) => this.serializeEffect(effect));
|
|
24718
|
-
|
|
24719
|
-
|
|
24720
|
-
|
|
24721
|
-
|
|
24722
|
-
|
|
24723
|
-
|
|
24724
|
-
|
|
24725
|
-
|
|
24726
|
-
|
|
25632
|
+
let acceptedCount = 0;
|
|
25633
|
+
const rejected = [];
|
|
25634
|
+
try {
|
|
25635
|
+
await withTimeout(
|
|
25636
|
+
host.wsClient.call("effects.resetCatalog", {}),
|
|
25637
|
+
EFFECT_CATALOG_SYNC_TIMEOUT_MS,
|
|
25638
|
+
`effects.resetCatalog for sandbox ${host.sandboxId}`
|
|
25639
|
+
);
|
|
25640
|
+
for (const batch of chunkItems(effects2, EFFECT_CATALOG_SYNC_BATCH_SIZE)) {
|
|
25641
|
+
const result = await withTimeout(
|
|
25642
|
+
host.wsClient.call("effects.addCatalog", {
|
|
25643
|
+
effects: batch
|
|
25644
|
+
}),
|
|
25645
|
+
EFFECT_CATALOG_SYNC_TIMEOUT_MS,
|
|
25646
|
+
`effects.addCatalog for sandbox ${host.sandboxId}`
|
|
25647
|
+
);
|
|
25648
|
+
acceptedCount += typeof result?.acceptedCount === "number" ? result.acceptedCount : 0;
|
|
25649
|
+
if (Array.isArray(result?.rejected)) {
|
|
25650
|
+
rejected.push(...result.rejected);
|
|
25651
|
+
}
|
|
25652
|
+
}
|
|
25653
|
+
} catch (error2) {
|
|
25654
|
+
if (!isUnsupportedEffectCatalogMutation(error2)) {
|
|
25655
|
+
throw error2;
|
|
25656
|
+
}
|
|
25657
|
+
const result = await withTimeout(
|
|
25658
|
+
host.wsClient.call("effects.publishCatalog", {
|
|
25659
|
+
effects: effects2
|
|
25660
|
+
}),
|
|
25661
|
+
EFFECT_CATALOG_SYNC_TIMEOUT_MS,
|
|
25662
|
+
`effects.publishCatalog for sandbox ${host.sandboxId}`
|
|
25663
|
+
);
|
|
25664
|
+
acceptedCount = typeof result?.acceptedCount === "number" ? result.acceptedCount : 0;
|
|
25665
|
+
if (Array.isArray(result?.rejected)) {
|
|
25666
|
+
rejected.push(...result.rejected);
|
|
25667
|
+
}
|
|
25668
|
+
}
|
|
24727
25669
|
if (acceptedCount === 0 && rejected.length > 0) {
|
|
24728
25670
|
const detail = rejected.map(
|
|
24729
25671
|
(entry) => `${entry.name || "unknown"}: ${entry.reason || "rejected"}`
|