@standardagents/builder 0.39.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/built-in-routes.js +671 -144
- package/dist/built-in-routes.js.map +1 -1
- package/dist/client/{ApiKeysView-AH5i-H6j.js → ApiKeysView-DoYvZZ7e.js} +1 -1
- package/dist/client/{CenteredContentView-DaBp0K-A.js → CenteredContentView-53PY0cqY.js} +1 -1
- package/dist/client/{CompositionView-yY1Q4M23.js → CompositionView-fp-0YnPt.js} +1 -1
- package/dist/client/{ConfirmDialog.vue_vue_type_script_setup_true_lang-Bwo5CJzF.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-Cvcagja2.js} +1 -1
- package/dist/client/{CopyButton.vue_vue_type_script_setup_true_lang-D0WYwWyA.js → CopyButton.vue_vue_type_script_setup_true_lang-jYvO2v1K.js} +1 -1
- package/dist/client/{DataTable.vue_vue_type_script_setup_true_lang-1wwPn2aY.js → DataTable.vue_vue_type_script_setup_true_lang-DQ3Ufa7y.js} +1 -1
- package/dist/client/{JsonViewer-Bi8Zdmir.js → JsonViewer-6aaGzutE.js} +1 -1
- package/dist/client/{LoginView-BIKahEU6.js → LoginView-DwpCmNw9.js} +1 -1
- package/dist/client/{MarketplaceView-DPDPVH68.js → MarketplaceView-Da02L0J5.js} +1 -1
- package/dist/client/{Modal.vue_vue_type_script_setup_true_lang-D1_rfOsy.js → Modal.vue_vue_type_script_setup_true_lang-Bi8OjiBf.js} +1 -1
- package/dist/client/{ModelModal.vue_vue_type_script_setup_true_lang-DSLeOdxr.js → ModelModal.vue_vue_type_script_setup_true_lang-cYZLOYY7.js} +1 -1
- package/dist/client/{ModelsView-Q2WXu1Gw.js → ModelsView-BLlHO9Ud.js} +1 -1
- package/dist/client/{PromptEditView-BzA-3n1w.js → PromptEditView-EeNwTDtT.js} +1 -1
- package/dist/client/{PromptModal-CJWh_cru.js → PromptModal-BkwrKJ2d.js} +1 -1
- package/dist/client/{PromptsView-BezNl-Et.js → PromptsView-D1r7tsLu.js} +1 -1
- package/dist/client/{ProvidersView-BuzSKxuT.js → ProvidersView-CmUDl5nM.js} +1 -1
- package/dist/client/{ThreadInspectorPane.vue_vue_type_script_setup_true_lang-DOxNp_3C.js → ThreadInspectorPane.vue_vue_type_script_setup_true_lang-cRs3tApQ.js} +1 -1
- package/dist/client/{ThreadsView-DPCpZA4J.js → ThreadsView-Bl5fSIO1.js} +1 -1
- package/dist/client/{ToolsView-DMjFMAhH.js → ToolsView-DlVEF8-7.js} +1 -1
- package/dist/client/{UsersView-B7jXLNQs.js → UsersView-CGlA7a7R.js} +1 -1
- package/dist/client/{VariablesView-CF7x0G8g.js → VariablesView-BpYmJL4V.js} +1 -1
- package/dist/client/index-CKtIkI0N.js +6 -0
- package/dist/client/index.html +1 -1
- package/dist/{discovery-DiMJWisl.d.ts → discovery-DZ7fv-b4.d.ts} +3 -2
- package/dist/{index-yIcqf7DC.d.ts → index-9MaIifn3.d.ts} +7 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1170 -563
- package/dist/index.js.map +1 -1
- package/dist/packing.d.ts +5 -3
- package/dist/packing.js +180 -5
- package/dist/packing.js.map +1 -1
- package/dist/plugin.js +252 -17
- package/dist/plugin.js.map +1 -1
- package/dist/runtime.d.ts +25 -38
- package/dist/runtime.js +1328 -958
- package/dist/runtime.js.map +1 -1
- package/dist/test.d.ts +2 -2
- package/dist/{types-Bpe7IANZ.d.ts → types-BMnBYNwn.d.ts} +3 -1
- package/package.json +5 -5
- package/dist/client/index-eGECJFYe.js +0 -6
package/dist/built-in-routes.js
CHANGED
|
@@ -1462,6 +1462,9 @@ function normalizeToolCallMessageSequence(messages) {
|
|
|
1462
1462
|
for (const message of messages) {
|
|
1463
1463
|
const isAssistantToolCallMessage = message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0;
|
|
1464
1464
|
if (!pending) {
|
|
1465
|
+
if (message.role === "tool") {
|
|
1466
|
+
continue;
|
|
1467
|
+
}
|
|
1465
1468
|
if (!isAssistantToolCallMessage) {
|
|
1466
1469
|
normalized.push(message);
|
|
1467
1470
|
continue;
|
|
@@ -6677,6 +6680,255 @@ var init_context = __esm({
|
|
|
6677
6680
|
}
|
|
6678
6681
|
});
|
|
6679
6682
|
|
|
6683
|
+
// src/packing/resolver.ts
|
|
6684
|
+
function parseQualifiedName(name15) {
|
|
6685
|
+
if (name15.startsWith("@")) {
|
|
6686
|
+
const firstSlash = name15.indexOf("/");
|
|
6687
|
+
if (firstSlash === -1) {
|
|
6688
|
+
return [null, name15];
|
|
6689
|
+
}
|
|
6690
|
+
const secondSlash = name15.indexOf("/", firstSlash + 1);
|
|
6691
|
+
if (secondSlash === -1) {
|
|
6692
|
+
return [null, name15];
|
|
6693
|
+
}
|
|
6694
|
+
return [name15.substring(0, secondSlash), name15.substring(secondSlash + 1)];
|
|
6695
|
+
}
|
|
6696
|
+
const separatorIndex = name15.indexOf("/");
|
|
6697
|
+
if (separatorIndex === -1) {
|
|
6698
|
+
return [null, name15];
|
|
6699
|
+
}
|
|
6700
|
+
return [name15.substring(0, separatorIndex), name15.substring(separatorIndex + 1)];
|
|
6701
|
+
}
|
|
6702
|
+
function qualifyName(packageId, shortName) {
|
|
6703
|
+
return `${packageId}/${shortName}`;
|
|
6704
|
+
}
|
|
6705
|
+
var init_resolver = __esm({
|
|
6706
|
+
"src/packing/resolver.ts"() {
|
|
6707
|
+
}
|
|
6708
|
+
});
|
|
6709
|
+
|
|
6710
|
+
// src/agents/ParentHookResolver.ts
|
|
6711
|
+
function packageOf(definition) {
|
|
6712
|
+
return definition?.__package ?? definition?._package;
|
|
6713
|
+
}
|
|
6714
|
+
function qualifyWithinPackage(name15, packageId) {
|
|
6715
|
+
if (!packageId || parseQualifiedName(name15)[0] !== null) {
|
|
6716
|
+
return name15;
|
|
6717
|
+
}
|
|
6718
|
+
return qualifyName(packageId, name15);
|
|
6719
|
+
}
|
|
6720
|
+
function promptHooks(prompt) {
|
|
6721
|
+
if (!prompt) return [];
|
|
6722
|
+
return Array.isArray(prompt.hooks) ? prompt.hooks : Array.isArray(prompt._hooks) ? prompt._hooks : [];
|
|
6723
|
+
}
|
|
6724
|
+
function promptTools(prompt) {
|
|
6725
|
+
if (!prompt) return [];
|
|
6726
|
+
return Array.isArray(prompt.tools) ? prompt.tools : Array.isArray(prompt._tools) ? prompt._tools : [];
|
|
6727
|
+
}
|
|
6728
|
+
function relationDescriptor(entry) {
|
|
6729
|
+
if (typeof entry === "string") {
|
|
6730
|
+
return {
|
|
6731
|
+
relationshipName: entry,
|
|
6732
|
+
implementingAgent: entry,
|
|
6733
|
+
explicitlyAgentShaped: false
|
|
6734
|
+
};
|
|
6735
|
+
}
|
|
6736
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
6737
|
+
return null;
|
|
6738
|
+
}
|
|
6739
|
+
const config = entry;
|
|
6740
|
+
if (typeof config.name !== "string" || !config.name) {
|
|
6741
|
+
return null;
|
|
6742
|
+
}
|
|
6743
|
+
const implementingAgent = typeof config.agent === "string" && config.agent ? config.agent : config.name;
|
|
6744
|
+
const explicitlyAgentShaped = "agent" in config || "blocking" in config || "resumable" in config || "immediate" in config || "parentCommunication" in config || "hidden" in config;
|
|
6745
|
+
return {
|
|
6746
|
+
relationshipName: config.name,
|
|
6747
|
+
implementingAgent,
|
|
6748
|
+
optional: typeof config.optional === "string" ? config.optional : void 0,
|
|
6749
|
+
explicitlyAgentShaped
|
|
6750
|
+
};
|
|
6751
|
+
}
|
|
6752
|
+
function hookLoader(host, owner, hookId) {
|
|
6753
|
+
const ownerPackage = packageOf(owner);
|
|
6754
|
+
if (!ownerPackage) {
|
|
6755
|
+
return host.hooks()[hookId];
|
|
6756
|
+
}
|
|
6757
|
+
return host.registry?.()?.packages?.[ownerPackage.packageId]?.hooks?.[hookId];
|
|
6758
|
+
}
|
|
6759
|
+
async function loadBinding(host, owner, hookId, hookType, context, required) {
|
|
6760
|
+
const loader = hookLoader(host, owner, hookId);
|
|
6761
|
+
if (!loader) {
|
|
6762
|
+
if (required) {
|
|
6763
|
+
throw new Error(
|
|
6764
|
+
`Required parent hook '${hookId}' was not found in the child agent namespace`
|
|
6765
|
+
);
|
|
6766
|
+
}
|
|
6767
|
+
return null;
|
|
6768
|
+
}
|
|
6769
|
+
let loaded;
|
|
6770
|
+
try {
|
|
6771
|
+
loaded = await loader();
|
|
6772
|
+
} catch (error) {
|
|
6773
|
+
if (required) throw error;
|
|
6774
|
+
console.error(`[Hooks] Failed to load hook '${hookId}':`, error);
|
|
6775
|
+
return null;
|
|
6776
|
+
}
|
|
6777
|
+
if (!loaded) {
|
|
6778
|
+
if (required) {
|
|
6779
|
+
throw new Error(`Required parent hook '${hookId}' did not export a hook definition`);
|
|
6780
|
+
}
|
|
6781
|
+
return null;
|
|
6782
|
+
}
|
|
6783
|
+
if (typeof loaded.id !== "string" || loaded.id !== hookId) {
|
|
6784
|
+
if (required) {
|
|
6785
|
+
throw new Error(`Required parent hook '${hookId}' exported a mismatched hook ID`);
|
|
6786
|
+
}
|
|
6787
|
+
return null;
|
|
6788
|
+
}
|
|
6789
|
+
if (typeof loaded.execute !== "function") {
|
|
6790
|
+
if (required) {
|
|
6791
|
+
throw new Error(`Required parent hook '${hookId}' did not export an execute function`);
|
|
6792
|
+
}
|
|
6793
|
+
return null;
|
|
6794
|
+
}
|
|
6795
|
+
if (USER_HOOK_NAMES.has(loaded.hook)) {
|
|
6796
|
+
if (required) {
|
|
6797
|
+
throw new Error(
|
|
6798
|
+
`Required parent hook '${hookId}' uses user-scoped hook type '${loaded.hook}'`
|
|
6799
|
+
);
|
|
6800
|
+
}
|
|
6801
|
+
return null;
|
|
6802
|
+
}
|
|
6803
|
+
if (!THREAD_HOOK_NAMES.has(loaded.hook)) {
|
|
6804
|
+
if (required) {
|
|
6805
|
+
throw new Error(`Required parent hook '${hookId}' exported invalid hook type '${loaded.hook}'`);
|
|
6806
|
+
}
|
|
6807
|
+
return null;
|
|
6808
|
+
}
|
|
6809
|
+
if (loaded.hook !== hookType) {
|
|
6810
|
+
return null;
|
|
6811
|
+
}
|
|
6812
|
+
return {
|
|
6813
|
+
id: hookId,
|
|
6814
|
+
hook: hookType,
|
|
6815
|
+
execute: loaded.execute,
|
|
6816
|
+
context
|
|
6817
|
+
};
|
|
6818
|
+
}
|
|
6819
|
+
async function resolveHooksForPrompt(input, hookType) {
|
|
6820
|
+
const agent = input.agent ?? await input.host.loadAgent(input.agentName);
|
|
6821
|
+
const agentPackage = packageOf(agent);
|
|
6822
|
+
const unqualifiedPromptName = input.promptName ?? agent.sideA?.prompt;
|
|
6823
|
+
const resolvedPromptName = unqualifiedPromptName ? qualifyWithinPackage(unqualifiedPromptName, agentPackage?.packageId) : void 0;
|
|
6824
|
+
const prompt = input.prompt ?? (resolvedPromptName ? await input.host.loadPrompt(resolvedPromptName) : void 0);
|
|
6825
|
+
const promptName = prompt?.name ?? prompt?.id ?? resolvedPromptName ?? "unknown_prompt";
|
|
6826
|
+
const before = [];
|
|
6827
|
+
const after = [];
|
|
6828
|
+
for (const entry of promptTools(prompt)) {
|
|
6829
|
+
const relation = relationDescriptor(entry);
|
|
6830
|
+
if (!relation) continue;
|
|
6831
|
+
if (relation.optional && input.isOptionalRelationshipEnabled && !await input.isOptionalRelationshipEnabled(relation.optional)) {
|
|
6832
|
+
continue;
|
|
6833
|
+
}
|
|
6834
|
+
const promptPackage = packageOf(prompt) ?? agentPackage;
|
|
6835
|
+
const childReference = qualifyWithinPackage(
|
|
6836
|
+
relation.implementingAgent,
|
|
6837
|
+
promptPackage?.packageId
|
|
6838
|
+
);
|
|
6839
|
+
let child;
|
|
6840
|
+
try {
|
|
6841
|
+
child = await input.host.loadAgent(childReference);
|
|
6842
|
+
} catch (error) {
|
|
6843
|
+
if (relation.explicitlyAgentShaped) throw error;
|
|
6844
|
+
continue;
|
|
6845
|
+
}
|
|
6846
|
+
if (child.type !== "dual_ai") continue;
|
|
6847
|
+
if (child.parentHooks !== void 0 && child.exposeAsTool !== true) {
|
|
6848
|
+
throw new Error(
|
|
6849
|
+
`Child agent '${childReference}' declares parentHooks but is not exposed as a tool`
|
|
6850
|
+
);
|
|
6851
|
+
}
|
|
6852
|
+
if (child.parentHooks !== void 0 && !Array.isArray(child.parentHooks)) {
|
|
6853
|
+
throw new Error(`Child agent '${childReference}' has an invalid parentHooks declaration`);
|
|
6854
|
+
}
|
|
6855
|
+
const requirements = child.parentHooks ?? [];
|
|
6856
|
+
const seenRequirements = /* @__PURE__ */ new Set();
|
|
6857
|
+
for (const requirement of requirements) {
|
|
6858
|
+
if (!requirement || typeof requirement !== "object" || typeof requirement.hook !== "string" || !requirement.hook || typeof requirement.reason !== "string" || !requirement.reason.trim() || requirement.stage !== void 0 && requirement.stage !== "before_parent" && requirement.stage !== "after_parent" || seenRequirements.has(requirement.hook)) {
|
|
6859
|
+
throw new Error(`Child agent '${childReference}' has an invalid parentHooks requirement`);
|
|
6860
|
+
}
|
|
6861
|
+
seenRequirements.add(requirement.hook);
|
|
6862
|
+
const loaded = await loadBinding(
|
|
6863
|
+
input.host,
|
|
6864
|
+
child,
|
|
6865
|
+
requirement.hook,
|
|
6866
|
+
hookType,
|
|
6867
|
+
{
|
|
6868
|
+
source: {
|
|
6869
|
+
kind: "child",
|
|
6870
|
+
relationshipName: relation.relationshipName,
|
|
6871
|
+
agentName: childReference,
|
|
6872
|
+
package: packageOf(child)
|
|
6873
|
+
}
|
|
6874
|
+
},
|
|
6875
|
+
true
|
|
6876
|
+
);
|
|
6877
|
+
if (!loaded) continue;
|
|
6878
|
+
if ((requirement.stage ?? "after_parent") === "before_parent") {
|
|
6879
|
+
before.push(loaded);
|
|
6880
|
+
} else {
|
|
6881
|
+
after.push(loaded);
|
|
6882
|
+
}
|
|
6883
|
+
}
|
|
6884
|
+
}
|
|
6885
|
+
const promptHookIds = promptHooks(prompt);
|
|
6886
|
+
const promptOwnsBaseHooks = promptHookIds.length > 0 && prompt !== void 0;
|
|
6887
|
+
const baseOwner = promptOwnsBaseHooks ? prompt : agent;
|
|
6888
|
+
const baseIds = promptHookIds.length > 0 ? promptHookIds : Array.isArray(agent.hooks) ? agent.hooks : [];
|
|
6889
|
+
const baseContext = promptOwnsBaseHooks ? { source: { kind: "prompt", promptName } } : { source: { kind: "agent", agentName: input.agentName } };
|
|
6890
|
+
const base = [];
|
|
6891
|
+
for (const hookId of baseIds) {
|
|
6892
|
+
const loaded = await loadBinding(
|
|
6893
|
+
input.host,
|
|
6894
|
+
baseOwner,
|
|
6895
|
+
hookId,
|
|
6896
|
+
hookType,
|
|
6897
|
+
baseContext,
|
|
6898
|
+
false
|
|
6899
|
+
);
|
|
6900
|
+
if (loaded) base.push(loaded);
|
|
6901
|
+
}
|
|
6902
|
+
return [...before, ...base, ...after];
|
|
6903
|
+
}
|
|
6904
|
+
var USER_HOOK_NAMES, THREAD_HOOK_NAMES;
|
|
6905
|
+
var init_ParentHookResolver = __esm({
|
|
6906
|
+
"src/agents/ParentHookResolver.ts"() {
|
|
6907
|
+
init_resolver();
|
|
6908
|
+
USER_HOOK_NAMES = /* @__PURE__ */ new Set([
|
|
6909
|
+
"user_client_attached",
|
|
6910
|
+
"user_client_detached",
|
|
6911
|
+
"user_value_changed"
|
|
6912
|
+
]);
|
|
6913
|
+
THREAD_HOOK_NAMES = /* @__PURE__ */ new Set([
|
|
6914
|
+
"after_thread_created",
|
|
6915
|
+
"after_subagent_created",
|
|
6916
|
+
"after_system_message",
|
|
6917
|
+
"filter_messages",
|
|
6918
|
+
"prefilter_llm_history",
|
|
6919
|
+
"before_create_message",
|
|
6920
|
+
"after_create_message",
|
|
6921
|
+
"before_update_message",
|
|
6922
|
+
"after_update_message",
|
|
6923
|
+
"before_store_tool_result",
|
|
6924
|
+
"after_tool_call_success",
|
|
6925
|
+
"after_tool_call_failure",
|
|
6926
|
+
"tool_call_started",
|
|
6927
|
+
"tool_call_done"
|
|
6928
|
+
]);
|
|
6929
|
+
}
|
|
6930
|
+
});
|
|
6931
|
+
|
|
6680
6932
|
// src/agents/FlowEngine.ts
|
|
6681
6933
|
var FlowEngine_exports = {};
|
|
6682
6934
|
__export(FlowEngine_exports, {
|
|
@@ -6693,6 +6945,7 @@ var init_FlowEngine = __esm({
|
|
|
6693
6945
|
init_context();
|
|
6694
6946
|
init_sessionTools();
|
|
6695
6947
|
init_ThreadStateImpl();
|
|
6948
|
+
init_ParentHookResolver();
|
|
6696
6949
|
IMMEDIATE_BOOTSTRAP_TOOL_NAME = "bootstrap_immediate_subagent";
|
|
6697
6950
|
HookBlockedExecutionError = class extends Error {
|
|
6698
6951
|
constructor(message) {
|
|
@@ -7035,7 +7288,8 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
7035
7288
|
_variables: def.variables ?? [],
|
|
7036
7289
|
_env: def.env ?? def.tenvs ?? {},
|
|
7037
7290
|
_requiredSchema: def.requiredSchema ?? null,
|
|
7038
|
-
_hooks: def.hooks ?? []
|
|
7291
|
+
_hooks: def.hooks ?? [],
|
|
7292
|
+
_package: def.__package
|
|
7039
7293
|
};
|
|
7040
7294
|
}
|
|
7041
7295
|
/**
|
|
@@ -7425,6 +7679,8 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
7425
7679
|
type: newAgentDef.type,
|
|
7426
7680
|
created_at: Date.now(),
|
|
7427
7681
|
max_session_turns: newAgentDef.maxSessionTurns ?? null,
|
|
7682
|
+
hooks: newAgentDef.hooks ?? [],
|
|
7683
|
+
_package: newAgentDef.__package,
|
|
7428
7684
|
side_a_label: newAgentDef.sideA?.label ?? null,
|
|
7429
7685
|
side_a_agent_prompt: newAgentDef.sideA?.prompt ?? null,
|
|
7430
7686
|
side_a_stop_on_response: newAgentDef.sideA?.stopOnResponse ?? true,
|
|
@@ -7515,28 +7771,12 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
7515
7771
|
state.promptPath = [sideAPrompt.name];
|
|
7516
7772
|
state.pendingImmediateAfterHandoff = true;
|
|
7517
7773
|
if (userMessageContent || userMessageAttachments) {
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
role: "user",
|
|
7523
|
-
content: userMessageContent || "",
|
|
7524
|
-
created_at: handoffTimestamp,
|
|
7525
|
-
attachments: userMessageAttachments
|
|
7526
|
-
};
|
|
7527
|
-
await state.storage.sql.exec(
|
|
7528
|
-
`INSERT INTO messages (id, role, content, attachments, created_at, prompt) VALUES (?, ?, ?, ?, ?, ?)`,
|
|
7529
|
-
handoffMessage.id,
|
|
7530
|
-
handoffMessage.role,
|
|
7531
|
-
handoffMessage.content,
|
|
7532
|
-
handoffMessage.attachments || null,
|
|
7533
|
-
handoffMessage.created_at,
|
|
7774
|
+
await this.persistHandoffUserMessage(
|
|
7775
|
+
state,
|
|
7776
|
+
userMessageContent || "",
|
|
7777
|
+
userMessageAttachments,
|
|
7534
7778
|
sideAPrompt.name
|
|
7535
7779
|
);
|
|
7536
|
-
state.messageHistory.push(handoffMessage);
|
|
7537
|
-
if (state.emitMessage) {
|
|
7538
|
-
state.emitMessage(handoffMessage);
|
|
7539
|
-
}
|
|
7540
7780
|
}
|
|
7541
7781
|
state.pendingHandoff = void 0;
|
|
7542
7782
|
state.emitTelemetry?.({
|
|
@@ -7551,6 +7791,37 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
7551
7791
|
throw error;
|
|
7552
7792
|
}
|
|
7553
7793
|
}
|
|
7794
|
+
/**
|
|
7795
|
+
* Persist the user message that rides an agent handoff, applying the
|
|
7796
|
+
* create-message lifecycle hooks like every other insertion path.
|
|
7797
|
+
*/
|
|
7798
|
+
static async persistHandoffUserMessage(state, content, attachments, promptName) {
|
|
7799
|
+
let handoffMessage = {
|
|
7800
|
+
id: crypto.randomUUID(),
|
|
7801
|
+
role: "user",
|
|
7802
|
+
content,
|
|
7803
|
+
created_at: Date.now() * 1e3,
|
|
7804
|
+
status: "completed",
|
|
7805
|
+
attachments: attachments ?? null
|
|
7806
|
+
};
|
|
7807
|
+
handoffMessage = await this.runBeforeCreateMessageHook(state, handoffMessage);
|
|
7808
|
+
await state.storage.sql.exec(
|
|
7809
|
+
`INSERT INTO messages (id, role, content, attachments, created_at, status, silent, prompt) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
7810
|
+
handoffMessage.id,
|
|
7811
|
+
handoffMessage.role,
|
|
7812
|
+
handoffMessage.content,
|
|
7813
|
+
handoffMessage.attachments || null,
|
|
7814
|
+
handoffMessage.created_at,
|
|
7815
|
+
handoffMessage.status ?? "completed",
|
|
7816
|
+
handoffMessage.silent ? 1 : 0,
|
|
7817
|
+
promptName
|
|
7818
|
+
);
|
|
7819
|
+
state.messageHistory.push(handoffMessage);
|
|
7820
|
+
await this.runAfterCreateMessageHook(state, handoffMessage);
|
|
7821
|
+
if (state.emitMessage) {
|
|
7822
|
+
state.emitMessage(handoffMessage);
|
|
7823
|
+
}
|
|
7824
|
+
}
|
|
7554
7825
|
static isEnabledEnvFlag(value) {
|
|
7555
7826
|
if (value === null || value === void 0) return false;
|
|
7556
7827
|
const normalized = value.trim().toLowerCase();
|
|
@@ -7570,7 +7841,7 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
7570
7841
|
return null;
|
|
7571
7842
|
}
|
|
7572
7843
|
return await stub.resolveThreadEnv({
|
|
7573
|
-
threadId: state.
|
|
7844
|
+
threadId: state.thread.metadata.id,
|
|
7574
7845
|
property,
|
|
7575
7846
|
promptName: state.prompt?.name
|
|
7576
7847
|
});
|
|
@@ -8092,8 +8363,8 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
8092
8363
|
state.context[key] = existing;
|
|
8093
8364
|
}
|
|
8094
8365
|
static async runImmediateToolsIfNeeded(state) {
|
|
8095
|
-
const
|
|
8096
|
-
if (
|
|
8366
|
+
const promptTools2 = Array.isArray(state.prompt._tools) ? state.prompt._tools : [];
|
|
8367
|
+
if (promptTools2.length === 0) {
|
|
8097
8368
|
return false;
|
|
8098
8369
|
}
|
|
8099
8370
|
if (!state.immediatePromptRuns) {
|
|
@@ -8129,7 +8400,7 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
8129
8400
|
(activeInstanceCounts.get(child.name) ?? 0) + 1
|
|
8130
8401
|
);
|
|
8131
8402
|
}
|
|
8132
|
-
for (const toolConfig of
|
|
8403
|
+
for (const toolConfig of promptTools2) {
|
|
8133
8404
|
if (!toolConfig || typeof toolConfig !== "object") {
|
|
8134
8405
|
continue;
|
|
8135
8406
|
}
|
|
@@ -8295,10 +8566,10 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
8295
8566
|
* model's to clean up, and terminate_subagent on an infrastructure child
|
|
8296
8567
|
* kills work the runtime depends on. Static and pure for direct testing.
|
|
8297
8568
|
*/
|
|
8298
|
-
static filterModelVisibleSubagents(registry,
|
|
8569
|
+
static filterModelVisibleSubagents(registry, promptTools2) {
|
|
8299
8570
|
if (registry.length === 0) return registry;
|
|
8300
8571
|
const hidden = /* @__PURE__ */ new Set();
|
|
8301
|
-
for (const config of
|
|
8572
|
+
for (const config of promptTools2 ?? []) {
|
|
8302
8573
|
if (typeof config === "object" && config !== null && "name" in config && config.hidden === true) {
|
|
8303
8574
|
hidden.add(config.name);
|
|
8304
8575
|
}
|
|
@@ -8448,7 +8719,16 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
8448
8719
|
role: "system",
|
|
8449
8720
|
content: systemPromptText
|
|
8450
8721
|
});
|
|
8451
|
-
const
|
|
8722
|
+
const historySnapshot = state.messageHistory.filter(
|
|
8723
|
+
(msg) => msg.status !== "pending"
|
|
8724
|
+
);
|
|
8725
|
+
const filteredHistory = await this.runFilterMessagesHook(
|
|
8726
|
+
state.thread.instance,
|
|
8727
|
+
state,
|
|
8728
|
+
historySnapshot
|
|
8729
|
+
);
|
|
8730
|
+
const contextHistory = this.filterOrphanedToolCalls(filteredHistory);
|
|
8731
|
+
const completedMessages = contextHistory.filter(
|
|
8452
8732
|
(msg) => msg.status !== "pending"
|
|
8453
8733
|
);
|
|
8454
8734
|
const recentMessageThreshold = state.prompt.recentImageThreshold ?? 10;
|
|
@@ -9319,8 +9599,8 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9319
9599
|
try {
|
|
9320
9600
|
const nativeTools = await this.loadNativeTools(state);
|
|
9321
9601
|
tools.push(...nativeTools);
|
|
9322
|
-
const
|
|
9323
|
-
tools.push(...
|
|
9602
|
+
const promptTools2 = await this.loadPromptTools(state);
|
|
9603
|
+
tools.push(...promptTools2);
|
|
9324
9604
|
const agentTools = await this.loadAgentTools(state);
|
|
9325
9605
|
tools.push(...agentTools);
|
|
9326
9606
|
const toolNameSources = /* @__PURE__ */ new Map();
|
|
@@ -9329,7 +9609,7 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9329
9609
|
sources.add("native tool");
|
|
9330
9610
|
toolNameSources.set(tool3.function.name, sources);
|
|
9331
9611
|
}
|
|
9332
|
-
for (const tool3 of
|
|
9612
|
+
for (const tool3 of promptTools2) {
|
|
9333
9613
|
const sources = toolNameSources.get(tool3.function.name) || /* @__PURE__ */ new Set();
|
|
9334
9614
|
sources.add("prompt");
|
|
9335
9615
|
toolNameSources.set(tool3.function.name, sources);
|
|
@@ -9471,24 +9751,8 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9471
9751
|
// Hook Resolution Helpers
|
|
9472
9752
|
// ==========================================================================
|
|
9473
9753
|
/**
|
|
9474
|
-
*
|
|
9475
|
-
*
|
|
9476
|
-
*
|
|
9477
|
-
* @param state - Flow state with prompt and agent configuration
|
|
9478
|
-
* @returns Array of hook IDs to execute
|
|
9479
|
-
*/
|
|
9480
|
-
static getActiveHookIds(state) {
|
|
9481
|
-
if (state.prompt?._hooks !== void 0 && state.prompt._hooks.length > 0) {
|
|
9482
|
-
return state.prompt._hooks;
|
|
9483
|
-
}
|
|
9484
|
-
if (state.agentConfig.hooks !== void 0 && state.agentConfig.hooks.length > 0) {
|
|
9485
|
-
return state.agentConfig.hooks;
|
|
9486
|
-
}
|
|
9487
|
-
return [];
|
|
9488
|
-
}
|
|
9489
|
-
/**
|
|
9490
|
-
* Get hooks of a specific type from the active hook IDs.
|
|
9491
|
-
* Returns typed hook executors in the order they appear in the hooks array.
|
|
9754
|
+
* Resolve hooks of a specific type for the active prompt, including required
|
|
9755
|
+
* hooks contributed automatically by its enabled direct child agents.
|
|
9492
9756
|
*
|
|
9493
9757
|
* @template K - The hook type name (ensures type-safe executors)
|
|
9494
9758
|
* @param state - Flow state with hook configuration
|
|
@@ -9496,24 +9760,17 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9496
9760
|
* @returns Array of typed hook executor functions
|
|
9497
9761
|
*/
|
|
9498
9762
|
static async getHooksForType(state, hookType) {
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
|
|
9507
|
-
|
|
9508
|
-
|
|
9509
|
-
|
|
9510
|
-
executors.push(hookDef.execute);
|
|
9511
|
-
}
|
|
9512
|
-
} catch (error) {
|
|
9513
|
-
console.error(`[Hooks] Failed to load hook '${hookId}':`, error);
|
|
9514
|
-
}
|
|
9515
|
-
}
|
|
9516
|
-
return executors;
|
|
9763
|
+
return await resolveHooksForPrompt(
|
|
9764
|
+
{
|
|
9765
|
+
host: state.thread.instance,
|
|
9766
|
+
agentName: state.agentConfig.id,
|
|
9767
|
+
agent: state.agentConfig,
|
|
9768
|
+
promptName: state.prompt?.id,
|
|
9769
|
+
prompt: state.prompt,
|
|
9770
|
+
isOptionalRelationshipEnabled: (envName) => this.isOptionalToolEnabled(state, envName)
|
|
9771
|
+
},
|
|
9772
|
+
hookType
|
|
9773
|
+
);
|
|
9517
9774
|
}
|
|
9518
9775
|
// ==========================================================================
|
|
9519
9776
|
// Hook Runner Methods
|
|
@@ -9531,9 +9788,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9531
9788
|
if (executors.length === 0) return messages;
|
|
9532
9789
|
let result = messages;
|
|
9533
9790
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9534
|
-
for (const
|
|
9791
|
+
for (const { execute, context } of executors) {
|
|
9535
9792
|
try {
|
|
9536
|
-
result = await
|
|
9793
|
+
result = await execute(threadState, result, context);
|
|
9537
9794
|
} catch (error) {
|
|
9538
9795
|
if (error && typeof error === "object" && error.block === true) {
|
|
9539
9796
|
throw new HookBlockedExecutionError(error instanceof Error ? error.message : String(error));
|
|
@@ -9551,9 +9808,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9551
9808
|
if (executors.length === 0) return systemMessage;
|
|
9552
9809
|
let result = systemMessage;
|
|
9553
9810
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9554
|
-
for (const
|
|
9811
|
+
for (const { execute, context } of executors) {
|
|
9555
9812
|
try {
|
|
9556
|
-
const next = await
|
|
9813
|
+
const next = await execute(threadState, result, context);
|
|
9557
9814
|
if (next !== null && next !== void 0) {
|
|
9558
9815
|
result = next;
|
|
9559
9816
|
}
|
|
@@ -9570,9 +9827,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9570
9827
|
const executors = await this.getHooksForType(state, "after_subagent_created");
|
|
9571
9828
|
if (executors.length === 0) return;
|
|
9572
9829
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9573
|
-
for (const
|
|
9830
|
+
for (const { execute, context } of executors) {
|
|
9574
9831
|
try {
|
|
9575
|
-
await
|
|
9832
|
+
await execute(threadState, childState, context);
|
|
9576
9833
|
} catch (error) {
|
|
9577
9834
|
console.error("[Hooks] \u2717 Error running after_subagent_created hook:", error);
|
|
9578
9835
|
}
|
|
@@ -9586,20 +9843,27 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9586
9843
|
* @param message - Message object to be created
|
|
9587
9844
|
* @returns Processed message (or original if hook doesn't exist/fails)
|
|
9588
9845
|
*/
|
|
9589
|
-
static async runBeforeCreateMessageHook(state, message) {
|
|
9846
|
+
static async runBeforeCreateMessageHook(state, message, threadStateOverride, options) {
|
|
9590
9847
|
const executors = await this.getHooksForType(state, "before_create_message");
|
|
9591
9848
|
if (executors.length === 0) return message;
|
|
9592
9849
|
let result = message;
|
|
9593
|
-
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9594
|
-
for (const
|
|
9850
|
+
const threadState = threadStateOverride ?? ThreadStateImpl.fromFlowState(state);
|
|
9851
|
+
for (const { execute, context } of executors) {
|
|
9595
9852
|
try {
|
|
9596
|
-
const hooked = await
|
|
9853
|
+
const hooked = await execute(
|
|
9854
|
+
threadState,
|
|
9855
|
+
_FlowEngine.rowToHookMessage(result),
|
|
9856
|
+
context
|
|
9857
|
+
);
|
|
9597
9858
|
result = {
|
|
9598
9859
|
...result,
|
|
9599
9860
|
...hooked,
|
|
9600
9861
|
attachments: hooked.attachments === void 0 ? result.attachments : hooked.attachments === null ? null : typeof hooked.attachments === "string" ? hooked.attachments : JSON.stringify(hooked.attachments)
|
|
9601
9862
|
};
|
|
9602
9863
|
} catch (error) {
|
|
9864
|
+
if (options?.propagateHookErrors) {
|
|
9865
|
+
throw error;
|
|
9866
|
+
}
|
|
9603
9867
|
console.error("[Hooks] \u2717 Error running before_create_message hook:", error);
|
|
9604
9868
|
}
|
|
9605
9869
|
}
|
|
@@ -9612,13 +9876,13 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9612
9876
|
* @param state - Flow state with execution context
|
|
9613
9877
|
* @param message - The created message object
|
|
9614
9878
|
*/
|
|
9615
|
-
static async runAfterCreateMessageHook(state, message) {
|
|
9879
|
+
static async runAfterCreateMessageHook(state, message, threadStateOverride) {
|
|
9616
9880
|
const executors = await this.getHooksForType(state, "after_create_message");
|
|
9617
9881
|
if (executors.length === 0) return;
|
|
9618
|
-
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9619
|
-
for (const
|
|
9882
|
+
const threadState = threadStateOverride ?? ThreadStateImpl.fromFlowState(state);
|
|
9883
|
+
for (const { execute, context } of executors) {
|
|
9620
9884
|
try {
|
|
9621
|
-
await
|
|
9885
|
+
await execute(threadState, _FlowEngine.rowToHookMessage(message), context);
|
|
9622
9886
|
} catch (error) {
|
|
9623
9887
|
console.error("[Hooks] \u2717 Error running after_create_message hook:", error);
|
|
9624
9888
|
}
|
|
@@ -9659,9 +9923,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9659
9923
|
if (executors.length === 0) return updates;
|
|
9660
9924
|
let result = updates;
|
|
9661
9925
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9662
|
-
for (const
|
|
9926
|
+
for (const { execute, context } of executors) {
|
|
9663
9927
|
try {
|
|
9664
|
-
result = await
|
|
9928
|
+
result = await execute(threadState, messageId, result, context);
|
|
9665
9929
|
} catch (error) {
|
|
9666
9930
|
console.error("[Hooks] \u2717 Error running before_update_message hook:", error);
|
|
9667
9931
|
}
|
|
@@ -9679,9 +9943,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9679
9943
|
const executors = await this.getHooksForType(state, "after_update_message");
|
|
9680
9944
|
if (executors.length === 0) return;
|
|
9681
9945
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9682
|
-
for (const
|
|
9946
|
+
for (const { execute, context } of executors) {
|
|
9683
9947
|
try {
|
|
9684
|
-
await
|
|
9948
|
+
await execute(threadState, _FlowEngine.rowToHookMessage(message), context);
|
|
9685
9949
|
} catch (error) {
|
|
9686
9950
|
console.error("[Hooks] \u2717 Error running after_update_message hook:", error);
|
|
9687
9951
|
}
|
|
@@ -9701,9 +9965,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9701
9965
|
if (executors.length === 0) return toolResult;
|
|
9702
9966
|
let result = toolResult;
|
|
9703
9967
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9704
|
-
for (const
|
|
9968
|
+
for (const { execute, context } of executors) {
|
|
9705
9969
|
try {
|
|
9706
|
-
result = await
|
|
9970
|
+
result = await execute(threadState, toolCall, result, context);
|
|
9707
9971
|
} catch (error) {
|
|
9708
9972
|
console.error("[Hooks] \u2717 Error running before_store_tool_result hook:", error);
|
|
9709
9973
|
}
|
|
@@ -9723,10 +9987,10 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9723
9987
|
if (executors.length === 0) return toolResult;
|
|
9724
9988
|
let result = toolResult;
|
|
9725
9989
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9726
|
-
for (const
|
|
9990
|
+
for (const { execute, context } of executors) {
|
|
9727
9991
|
if (result === null) break;
|
|
9728
9992
|
try {
|
|
9729
|
-
result = await
|
|
9993
|
+
result = await execute(threadState, toolCall, result, context);
|
|
9730
9994
|
} catch (error) {
|
|
9731
9995
|
console.error("[Hooks] \u2717 Error running after_tool_call_success hook:", error);
|
|
9732
9996
|
}
|
|
@@ -9746,10 +10010,10 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9746
10010
|
if (executors.length === 0) return toolResult;
|
|
9747
10011
|
let result = toolResult;
|
|
9748
10012
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9749
|
-
for (const
|
|
10013
|
+
for (const { execute, context } of executors) {
|
|
9750
10014
|
if (result === null) break;
|
|
9751
10015
|
try {
|
|
9752
|
-
result = await
|
|
10016
|
+
result = await execute(threadState, toolCall, result, context);
|
|
9753
10017
|
} catch (error) {
|
|
9754
10018
|
console.error("[Hooks] \u2717 Error running after_tool_call_failure hook:", error);
|
|
9755
10019
|
}
|
|
@@ -9779,9 +10043,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9779
10043
|
const executors = await this.getHooksForType(state, "tool_call_started");
|
|
9780
10044
|
if (executors.length === 0) return;
|
|
9781
10045
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9782
|
-
for (const
|
|
10046
|
+
for (const { execute, context } of executors) {
|
|
9783
10047
|
try {
|
|
9784
|
-
await
|
|
10048
|
+
await execute(threadState, toolCall, progress, context);
|
|
9785
10049
|
} catch (error) {
|
|
9786
10050
|
console.error("[Hooks] \u2717 Error running tool_call_started hook:", error);
|
|
9787
10051
|
}
|
|
@@ -9809,9 +10073,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9809
10073
|
const executors = await this.getHooksForType(state, "tool_call_done");
|
|
9810
10074
|
if (executors.length === 0) return;
|
|
9811
10075
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9812
|
-
for (const
|
|
10076
|
+
for (const { execute, context } of executors) {
|
|
9813
10077
|
try {
|
|
9814
|
-
await
|
|
10078
|
+
await execute(threadState, toolCall, toolResult, context);
|
|
9815
10079
|
} catch (error) {
|
|
9816
10080
|
console.error("[Hooks] \u2717 Error running tool_call_done hook:", error);
|
|
9817
10081
|
}
|
|
@@ -10116,7 +10380,7 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
10116
10380
|
}
|
|
10117
10381
|
existingPathMessages.add(content);
|
|
10118
10382
|
const attachmentsJson = JSON.stringify([ref]);
|
|
10119
|
-
|
|
10383
|
+
let silentMessage = {
|
|
10120
10384
|
id: crypto.randomUUID(),
|
|
10121
10385
|
role: sourceMessage.role,
|
|
10122
10386
|
content,
|
|
@@ -10127,6 +10391,7 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
10127
10391
|
parent_id: parentId,
|
|
10128
10392
|
depth
|
|
10129
10393
|
};
|
|
10394
|
+
silentMessage = await this.runBeforeCreateMessageHook(state, silentMessage);
|
|
10130
10395
|
await state.storage.sql.exec(
|
|
10131
10396
|
`
|
|
10132
10397
|
INSERT INTO messages (
|
|
@@ -10137,15 +10402,16 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
10137
10402
|
silentMessage.id,
|
|
10138
10403
|
silentMessage.role,
|
|
10139
10404
|
silentMessage.content,
|
|
10140
|
-
|
|
10141
|
-
1,
|
|
10405
|
+
silentMessage.attachments ?? null,
|
|
10406
|
+
silentMessage.silent ? 1 : 0,
|
|
10142
10407
|
silentMessage.created_at,
|
|
10143
|
-
silentMessage.status,
|
|
10408
|
+
silentMessage.status ?? "completed",
|
|
10144
10409
|
silentMessage.parent_id,
|
|
10145
10410
|
silentMessage.depth,
|
|
10146
10411
|
currentPrompt
|
|
10147
10412
|
);
|
|
10148
10413
|
state.messageHistory.push(silentMessage);
|
|
10414
|
+
await this.runAfterCreateMessageHook(state, silentMessage);
|
|
10149
10415
|
if (state.emitMessage) {
|
|
10150
10416
|
state.emitMessage(silentMessage);
|
|
10151
10417
|
}
|
|
@@ -10684,7 +10950,7 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
10684
10950
|
*/
|
|
10685
10951
|
static async loadMessageHistory(state) {
|
|
10686
10952
|
const storage = state.storage;
|
|
10687
|
-
|
|
10953
|
+
state.thread;
|
|
10688
10954
|
const includeParentHistory = state.prompt.include_chat ?? true;
|
|
10689
10955
|
const includeToolCalls = state.prompt.include_past_tools ?? true;
|
|
10690
10956
|
try {
|
|
@@ -10720,8 +10986,11 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
10720
10986
|
rows = cursor.toArray();
|
|
10721
10987
|
}
|
|
10722
10988
|
if (state.extraMessages && state.extraMessages.length > 0) {
|
|
10723
|
-
rows.
|
|
10724
|
-
rows.
|
|
10989
|
+
const persistedIds = new Set(rows.map((row) => row.id));
|
|
10990
|
+
rows.push(
|
|
10991
|
+
...state.extraMessages.filter((entry) => !persistedIds.has(entry.id))
|
|
10992
|
+
);
|
|
10993
|
+
rows.sort((a, b) => a.created_at - b.created_at);
|
|
10725
10994
|
}
|
|
10726
10995
|
const messages = rows.map((row) => ({
|
|
10727
10996
|
id: row.id,
|
|
@@ -10744,43 +11013,77 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
10744
11013
|
reasoning_content: row.reasoning_content,
|
|
10745
11014
|
reasoning_details: row.reasoning_details
|
|
10746
11015
|
}));
|
|
10747
|
-
return
|
|
10748
|
-
thread.instance,
|
|
10749
|
-
state,
|
|
10750
|
-
this.filterOrphanedToolCalls(messages)
|
|
10751
|
-
);
|
|
11016
|
+
return messages;
|
|
10752
11017
|
} catch (error) {
|
|
10753
11018
|
console.error("Error loading message history:", error);
|
|
10754
11019
|
return [];
|
|
10755
11020
|
}
|
|
10756
11021
|
}
|
|
10757
11022
|
/**
|
|
10758
|
-
*
|
|
10759
|
-
*
|
|
10760
|
-
*
|
|
10761
|
-
* @param thread - Thread instance with hooks registry
|
|
10762
|
-
* @param state - Flow state for hook context
|
|
10763
|
-
* @param rows - SQL rows from messages table
|
|
10764
|
-
* @returns Processed rows (or original if hook doesn't exist/fails)
|
|
11023
|
+
* Build request-context rows from persisted history.
|
|
11024
|
+
* Mutations and synthetic messages stay in the request context.
|
|
10765
11025
|
*/
|
|
10766
11026
|
static async runFilterMessagesHook(thread, state, messages) {
|
|
10767
11027
|
const executors = await this.getHooksForType(state, "filter_messages");
|
|
10768
11028
|
if (executors.length === 0) return messages;
|
|
10769
11029
|
let result = messages;
|
|
10770
11030
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
10771
|
-
for (const
|
|
11031
|
+
for (const { execute, context } of executors) {
|
|
10772
11032
|
try {
|
|
10773
11033
|
const byId = /* @__PURE__ */ new Map();
|
|
10774
11034
|
for (const row of result) if (row.id) byId.set(row.id, row);
|
|
10775
11035
|
const hookView = result.map((row) => _FlowEngine.rowToHookMessage(row));
|
|
10776
|
-
const kept = await
|
|
10777
|
-
result = kept.map((
|
|
11036
|
+
const kept = await execute(threadState, hookView, context);
|
|
11037
|
+
result = kept.map((hookedMessage) => {
|
|
11038
|
+
const original = hookedMessage.id ? byId.get(hookedMessage.id) : void 0;
|
|
11039
|
+
if (original) {
|
|
11040
|
+
return _FlowEngine.applyHookMessageToRow(original, hookedMessage);
|
|
11041
|
+
}
|
|
11042
|
+
return _FlowEngine.hookMessageToContextRow(hookedMessage);
|
|
11043
|
+
});
|
|
10778
11044
|
} catch (error) {
|
|
10779
11045
|
console.error("[Hooks] \u2717 Error running filter_messages hook:", error);
|
|
10780
11046
|
}
|
|
10781
11047
|
}
|
|
10782
11048
|
return result;
|
|
10783
11049
|
}
|
|
11050
|
+
/**
|
|
11051
|
+
* Copy a persisted row and apply hook edits. The original live-history
|
|
11052
|
+
* object is left unchanged.
|
|
11053
|
+
*/
|
|
11054
|
+
static applyHookMessageToRow(original, hooked) {
|
|
11055
|
+
const attachments = hooked.attachments === void 0 ? original.attachments : hooked.attachments === null ? null : typeof hooked.attachments === "string" ? hooked.attachments : JSON.stringify(hooked.attachments);
|
|
11056
|
+
return {
|
|
11057
|
+
...original,
|
|
11058
|
+
role: hooked.role ?? original.role,
|
|
11059
|
+
content: hooked.content !== void 0 ? hooked.content : original.content,
|
|
11060
|
+
name: hooked.name !== void 0 ? hooked.name : original.name,
|
|
11061
|
+
tool_calls: hooked.tool_calls !== void 0 ? hooked.tool_calls : original.tool_calls,
|
|
11062
|
+
tool_call_id: hooked.tool_call_id !== void 0 ? hooked.tool_call_id : original.tool_call_id,
|
|
11063
|
+
silent: hooked.silent !== void 0 ? hooked.silent : original.silent,
|
|
11064
|
+
attachments
|
|
11065
|
+
};
|
|
11066
|
+
}
|
|
11067
|
+
/**
|
|
11068
|
+
* Convert a synthetic hook message into a request-context-only builder row.
|
|
11069
|
+
*/
|
|
11070
|
+
static hookMessageToContextRow(hooked) {
|
|
11071
|
+
const attachments = hooked.attachments === void 0 || hooked.attachments === null ? hooked.attachments ?? null : typeof hooked.attachments === "string" ? hooked.attachments : JSON.stringify(hooked.attachments);
|
|
11072
|
+
return {
|
|
11073
|
+
id: hooked.id || crypto.randomUUID(),
|
|
11074
|
+
role: hooked.role,
|
|
11075
|
+
content: hooked.content ?? null,
|
|
11076
|
+
name: hooked.name ?? null,
|
|
11077
|
+
tool_calls: typeof hooked.tool_calls === "string" ? hooked.tool_calls : null,
|
|
11078
|
+
tool_call_id: hooked.tool_call_id ?? null,
|
|
11079
|
+
created_at: hooked.created_at ?? Date.now() * TIMESTAMP_MULTIPLIER,
|
|
11080
|
+
parent_id: hooked.parent_id ?? null,
|
|
11081
|
+
depth: hooked.depth ?? 0,
|
|
11082
|
+
silent: hooked.silent ?? false,
|
|
11083
|
+
status: "completed",
|
|
11084
|
+
attachments
|
|
11085
|
+
};
|
|
11086
|
+
}
|
|
10784
11087
|
/**
|
|
10785
11088
|
* Log an error to the logs table (best-effort)
|
|
10786
11089
|
* Creates a log entry with error details but no associated message_id
|
|
@@ -10951,7 +11254,7 @@ async function injectMessage(flow, options) {
|
|
|
10951
11254
|
const timestamp = Date.now() * TIMESTAMP_MULTIPLIER;
|
|
10952
11255
|
const silent = options.silent ?? false;
|
|
10953
11256
|
const forceTopLevel = options.forceTopLevel ?? false;
|
|
10954
|
-
|
|
11257
|
+
let message = {
|
|
10955
11258
|
id: messageId,
|
|
10956
11259
|
role: options.role,
|
|
10957
11260
|
content: options.content,
|
|
@@ -10965,41 +11268,52 @@ async function injectMessage(flow, options) {
|
|
|
10965
11268
|
metadata: options.metadata
|
|
10966
11269
|
};
|
|
10967
11270
|
if (options.beforeMessageId) {
|
|
10968
|
-
const
|
|
10969
|
-
|
|
10970
|
-
options.beforeMessageId
|
|
11271
|
+
const liveTarget = flow.messageHistory.find(
|
|
11272
|
+
(entry) => entry.id === options.beforeMessageId
|
|
10971
11273
|
);
|
|
10972
|
-
|
|
10973
|
-
|
|
10974
|
-
|
|
10975
|
-
|
|
10976
|
-
|
|
11274
|
+
let targetCreatedAt = liveTarget?.created_at;
|
|
11275
|
+
if (targetCreatedAt === void 0) {
|
|
11276
|
+
const cursor = await flow.storage.sql.exec(
|
|
11277
|
+
`SELECT created_at FROM messages WHERE id = ?`,
|
|
11278
|
+
options.beforeMessageId
|
|
10977
11279
|
);
|
|
11280
|
+
const rows = cursor.toArray();
|
|
11281
|
+
const targetMessage = rows[0];
|
|
11282
|
+
if (!targetMessage) {
|
|
11283
|
+
throw new Error(
|
|
11284
|
+
`Message with id ${options.beforeMessageId} not found`
|
|
11285
|
+
);
|
|
11286
|
+
}
|
|
11287
|
+
targetCreatedAt = targetMessage.created_at;
|
|
10978
11288
|
}
|
|
10979
|
-
message.created_at =
|
|
11289
|
+
message.created_at = targetCreatedAt - 1;
|
|
10980
11290
|
}
|
|
10981
11291
|
const currentPrompt = flow.promptPath.length > 0 ? flow.promptPath[flow.promptPath.length - 1] : null;
|
|
10982
|
-
const
|
|
11292
|
+
const { FlowEngine: FlowEngine2 } = await Promise.resolve().then(() => (init_FlowEngine(), FlowEngine_exports));
|
|
11293
|
+
message = await FlowEngine2.runBeforeCreateMessageHook(flow, message, void 0, {
|
|
11294
|
+
propagateHookErrors: true
|
|
11295
|
+
});
|
|
11296
|
+
const metadataJson = message.metadata === void 0 ? null : JSON.stringify(message.metadata);
|
|
10983
11297
|
await flow.storage.sql.exec(
|
|
10984
11298
|
`INSERT INTO messages (id, role, content, name, tool_call_id, created_at, status, silent, parent_id, depth, metadata, prompt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
10985
|
-
|
|
11299
|
+
message.id,
|
|
10986
11300
|
message.role,
|
|
10987
11301
|
message.content,
|
|
10988
11302
|
message.name,
|
|
10989
11303
|
message.tool_call_id,
|
|
10990
11304
|
message.created_at,
|
|
10991
11305
|
message.status,
|
|
10992
|
-
silent ? 1 : 0,
|
|
11306
|
+
message.silent ? 1 : 0,
|
|
10993
11307
|
message.parent_id,
|
|
10994
11308
|
message.depth,
|
|
10995
11309
|
metadataJson,
|
|
10996
11310
|
currentPrompt
|
|
10997
11311
|
);
|
|
10998
|
-
|
|
10999
|
-
|
|
11000
|
-
|
|
11001
|
-
flow.messageHistory = await reloadHistory(flow);
|
|
11312
|
+
appendLiveExecutionHistory(flow, message, options.beforeMessageId);
|
|
11313
|
+
if (flow.prompt.include_chat === false || message.parent_id !== null || (message.depth ?? 0) > 0) {
|
|
11314
|
+
appendInjectedContextMessage(flow.extraMessages, message);
|
|
11002
11315
|
}
|
|
11316
|
+
await FlowEngine2.runAfterCreateMessageHook(flow, message);
|
|
11003
11317
|
if (flow.emitMessage) {
|
|
11004
11318
|
flow.emitMessage(message);
|
|
11005
11319
|
}
|
|
@@ -11008,10 +11322,41 @@ async function injectMessage(flow, options) {
|
|
|
11008
11322
|
}
|
|
11009
11323
|
return message;
|
|
11010
11324
|
}
|
|
11011
|
-
|
|
11012
|
-
const
|
|
11013
|
-
|
|
11014
|
-
|
|
11325
|
+
function appendLiveExecutionHistory(flow, message, beforeMessageId) {
|
|
11326
|
+
const history = flow.messageHistory;
|
|
11327
|
+
const existing = history.findIndex((entry) => entry.id === message.id);
|
|
11328
|
+
if (existing >= 0) {
|
|
11329
|
+
history.splice(existing, 1);
|
|
11330
|
+
}
|
|
11331
|
+
if (beforeMessageId) {
|
|
11332
|
+
const targetIndex = history.findIndex((entry) => entry.id === beforeMessageId);
|
|
11333
|
+
if (targetIndex >= 0) {
|
|
11334
|
+
history.splice(targetIndex, 0, message);
|
|
11335
|
+
return;
|
|
11336
|
+
}
|
|
11337
|
+
}
|
|
11338
|
+
const insertAt = history.findIndex(
|
|
11339
|
+
(entry) => entry.created_at > message.created_at
|
|
11340
|
+
);
|
|
11341
|
+
if (insertAt === -1) {
|
|
11342
|
+
history.push(message);
|
|
11343
|
+
return;
|
|
11344
|
+
}
|
|
11345
|
+
history.splice(insertAt, 0, message);
|
|
11346
|
+
}
|
|
11347
|
+
function appendInjectedContextMessage(extraMessages, message) {
|
|
11348
|
+
const existing = extraMessages.findIndex((entry) => entry.id === message.id);
|
|
11349
|
+
if (existing >= 0) {
|
|
11350
|
+
extraMessages.splice(existing, 1);
|
|
11351
|
+
}
|
|
11352
|
+
const insertAt = extraMessages.findIndex(
|
|
11353
|
+
(entry) => entry.created_at > message.created_at
|
|
11354
|
+
);
|
|
11355
|
+
if (insertAt === -1) {
|
|
11356
|
+
extraMessages.push(message);
|
|
11357
|
+
return;
|
|
11358
|
+
}
|
|
11359
|
+
extraMessages.splice(insertAt, 0, message);
|
|
11015
11360
|
}
|
|
11016
11361
|
function forceTurn(flow, side) {
|
|
11017
11362
|
if (flow.sequence.isHandling) {
|
|
@@ -14692,11 +15037,19 @@ async function extractPromptTools(sourceCode) {
|
|
|
14692
15037
|
result.tools.push(element.text);
|
|
14693
15038
|
} else if (ts.isObjectLiteralExpression(element)) {
|
|
14694
15039
|
result.hasSubpromptConfigs = true;
|
|
15040
|
+
let configuredName;
|
|
15041
|
+
let implementingAgent;
|
|
14695
15042
|
for (const objProp of element.properties) {
|
|
14696
|
-
if (ts.isPropertyAssignment(objProp) && ts.isIdentifier(objProp.name) &&
|
|
14697
|
-
|
|
15043
|
+
if (ts.isPropertyAssignment(objProp) && ts.isIdentifier(objProp.name) && ts.isStringLiteral(objProp.initializer)) {
|
|
15044
|
+
if (objProp.name.text === "name") {
|
|
15045
|
+
configuredName = objProp.initializer.text;
|
|
15046
|
+
} else if (objProp.name.text === "agent") {
|
|
15047
|
+
implementingAgent = objProp.initializer.text;
|
|
15048
|
+
}
|
|
14698
15049
|
}
|
|
14699
15050
|
}
|
|
15051
|
+
const dependencyName = implementingAgent ?? configuredName;
|
|
15052
|
+
if (dependencyName) result.tools.push(dependencyName);
|
|
14700
15053
|
}
|
|
14701
15054
|
}
|
|
14702
15055
|
}
|
|
@@ -14819,6 +15172,106 @@ async function extractAgentPrompts(sourceCode) {
|
|
|
14819
15172
|
visit2(sourceFile);
|
|
14820
15173
|
return result;
|
|
14821
15174
|
}
|
|
15175
|
+
async function extractAgentHooks(sourceCode) {
|
|
15176
|
+
const ts = await loadTypeScript();
|
|
15177
|
+
const sourceFile = ts.createSourceFile(
|
|
15178
|
+
"agent.ts",
|
|
15179
|
+
sourceCode,
|
|
15180
|
+
ts.ScriptTarget.ESNext,
|
|
15181
|
+
true
|
|
15182
|
+
);
|
|
15183
|
+
const arrays = /* @__PURE__ */ new Map();
|
|
15184
|
+
const result = {
|
|
15185
|
+
hooks: [],
|
|
15186
|
+
parentHooks: [],
|
|
15187
|
+
parentHookRequirements: []
|
|
15188
|
+
};
|
|
15189
|
+
const unwrapArray = (expression) => {
|
|
15190
|
+
let current = expression;
|
|
15191
|
+
while (ts.isParenthesizedExpression(current) || ts.isAsExpression(current) || ts.isSatisfiesExpression(current)) {
|
|
15192
|
+
current = current.expression;
|
|
15193
|
+
}
|
|
15194
|
+
if (ts.isArrayLiteralExpression(current)) return current;
|
|
15195
|
+
if (ts.isIdentifier(current)) return arrays.get(current.text) ?? null;
|
|
15196
|
+
return null;
|
|
15197
|
+
};
|
|
15198
|
+
for (const statement of sourceFile.statements) {
|
|
15199
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
15200
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
15201
|
+
if (ts.isIdentifier(declaration.name) && declaration.initializer) {
|
|
15202
|
+
const array44 = unwrapArray(declaration.initializer);
|
|
15203
|
+
if (array44) arrays.set(declaration.name.text, array44);
|
|
15204
|
+
}
|
|
15205
|
+
}
|
|
15206
|
+
}
|
|
15207
|
+
const pushUnique = (target, value) => {
|
|
15208
|
+
if (!target.includes(value)) target.push(value);
|
|
15209
|
+
};
|
|
15210
|
+
function visit2(node) {
|
|
15211
|
+
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "defineAgent" && node.arguments.length > 0 && ts.isObjectLiteralExpression(node.arguments[0])) {
|
|
15212
|
+
for (const property of node.arguments[0].properties) {
|
|
15213
|
+
if (!ts.isPropertyAssignment(property) || !ts.isIdentifier(property.name)) continue;
|
|
15214
|
+
const array44 = unwrapArray(property.initializer);
|
|
15215
|
+
if (!array44) continue;
|
|
15216
|
+
if (property.name.text === "hooks") {
|
|
15217
|
+
for (const element of array44.elements) {
|
|
15218
|
+
if (ts.isStringLiteral(element)) pushUnique(result.hooks, element.text);
|
|
15219
|
+
}
|
|
15220
|
+
}
|
|
15221
|
+
if (property.name.text === "parentHooks") {
|
|
15222
|
+
for (const element of array44.elements) {
|
|
15223
|
+
if (!ts.isObjectLiteralExpression(element)) continue;
|
|
15224
|
+
let hook;
|
|
15225
|
+
let reason;
|
|
15226
|
+
let stage;
|
|
15227
|
+
for (const requirement of element.properties) {
|
|
15228
|
+
if (ts.isPropertyAssignment(requirement) && ts.isIdentifier(requirement.name) && ts.isStringLiteral(requirement.initializer)) {
|
|
15229
|
+
if (requirement.name.text === "hook") hook = requirement.initializer.text;
|
|
15230
|
+
if (requirement.name.text === "reason") reason = requirement.initializer.text;
|
|
15231
|
+
if (requirement.name.text === "stage" && (requirement.initializer.text === "before_parent" || requirement.initializer.text === "after_parent")) {
|
|
15232
|
+
stage = requirement.initializer.text;
|
|
15233
|
+
}
|
|
15234
|
+
}
|
|
15235
|
+
}
|
|
15236
|
+
if (hook) {
|
|
15237
|
+
pushUnique(result.parentHooks, hook);
|
|
15238
|
+
if (reason) result.parentHookRequirements.push({ hook, reason, stage });
|
|
15239
|
+
}
|
|
15240
|
+
}
|
|
15241
|
+
}
|
|
15242
|
+
}
|
|
15243
|
+
}
|
|
15244
|
+
ts.forEachChild(node, visit2);
|
|
15245
|
+
}
|
|
15246
|
+
visit2(sourceFile);
|
|
15247
|
+
return result;
|
|
15248
|
+
}
|
|
15249
|
+
async function extractPromptHooks(sourceCode) {
|
|
15250
|
+
const ts = await loadTypeScript();
|
|
15251
|
+
const sourceFile = ts.createSourceFile(
|
|
15252
|
+
"prompt.ts",
|
|
15253
|
+
sourceCode,
|
|
15254
|
+
ts.ScriptTarget.ESNext,
|
|
15255
|
+
true
|
|
15256
|
+
);
|
|
15257
|
+
const hooks = [];
|
|
15258
|
+
function visit2(node) {
|
|
15259
|
+
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "definePrompt" && node.arguments.length > 0 && ts.isObjectLiteralExpression(node.arguments[0])) {
|
|
15260
|
+
for (const property of node.arguments[0].properties) {
|
|
15261
|
+
if (ts.isPropertyAssignment(property) && ts.isIdentifier(property.name) && property.name.text === "hooks" && ts.isArrayLiteralExpression(property.initializer)) {
|
|
15262
|
+
for (const element of property.initializer.elements) {
|
|
15263
|
+
if (ts.isStringLiteral(element) && !hooks.includes(element.text)) {
|
|
15264
|
+
hooks.push(element.text);
|
|
15265
|
+
}
|
|
15266
|
+
}
|
|
15267
|
+
}
|
|
15268
|
+
}
|
|
15269
|
+
}
|
|
15270
|
+
ts.forEachChild(node, visit2);
|
|
15271
|
+
}
|
|
15272
|
+
visit2(sourceFile);
|
|
15273
|
+
return hooks;
|
|
15274
|
+
}
|
|
14822
15275
|
async function extractAgentDescription(sourceCode) {
|
|
14823
15276
|
const ts = await loadTypeScript();
|
|
14824
15277
|
const sourceFile = ts.createSourceFile(
|
|
@@ -15074,6 +15527,13 @@ var init_packing_service = __esm({
|
|
|
15074
15527
|
});
|
|
15075
15528
|
const agentSource = fs4.readFileSync(agentFilePath, "utf-8");
|
|
15076
15529
|
const agentPrompts = await extractAgentPrompts(agentSource);
|
|
15530
|
+
const agentHooks = await extractAgentHooks(agentSource);
|
|
15531
|
+
for (const hookId of agentHooks.hooks) {
|
|
15532
|
+
await this.analyzeHook(hookId, agentsDir, analysis, false, `agent:${agentName}`);
|
|
15533
|
+
}
|
|
15534
|
+
for (const hookId of agentHooks.parentHooks) {
|
|
15535
|
+
await this.analyzeHook(hookId, agentsDir, analysis, true, `agent:${agentName}`);
|
|
15536
|
+
}
|
|
15077
15537
|
if (agentPrompts.sideA) {
|
|
15078
15538
|
analysis.primaryPrompt = agentPrompts.sideA;
|
|
15079
15539
|
await this.analyzePrompt(agentPrompts.sideA, agentsDir, analysis, /* @__PURE__ */ new Set(), `agent:${agentName}`);
|
|
@@ -15276,6 +15736,9 @@ var init_packing_service = __esm({
|
|
|
15276
15736
|
}
|
|
15277
15737
|
visited.add(`prompt:${promptName}`);
|
|
15278
15738
|
const promptSource = fs4.readFileSync(promptFilePath, "utf-8");
|
|
15739
|
+
for (const hookId of await extractPromptHooks(promptSource)) {
|
|
15740
|
+
await this.analyzeHook(hookId, agentsDir, analysis, false, thisKey);
|
|
15741
|
+
}
|
|
15279
15742
|
const modelName = await extractPromptModel(promptSource);
|
|
15280
15743
|
if (modelName) {
|
|
15281
15744
|
await this.analyzeModel(modelName, agentsDir, analysis, visited, thisKey);
|
|
@@ -15360,6 +15823,13 @@ var init_packing_service = __esm({
|
|
|
15360
15823
|
visited.add(`agent:${agentName}`);
|
|
15361
15824
|
const agentSource = fs4.readFileSync(agentFilePath, "utf-8");
|
|
15362
15825
|
const agentPrompts = await extractAgentPrompts(agentSource);
|
|
15826
|
+
const agentHooks = await extractAgentHooks(agentSource);
|
|
15827
|
+
for (const hookId of agentHooks.hooks) {
|
|
15828
|
+
await this.analyzeHook(hookId, agentsDir, analysis, false, thisKey);
|
|
15829
|
+
}
|
|
15830
|
+
for (const hookId of agentHooks.parentHooks) {
|
|
15831
|
+
await this.analyzeHook(hookId, agentsDir, analysis, true, thisKey);
|
|
15832
|
+
}
|
|
15363
15833
|
if (agentPrompts.sideA) {
|
|
15364
15834
|
await this.analyzePrompt(agentPrompts.sideA, agentsDir, analysis, visited, thisKey);
|
|
15365
15835
|
}
|
|
@@ -15367,6 +15837,27 @@ var init_packing_service = __esm({
|
|
|
15367
15837
|
await this.analyzePrompt(agentPrompts.sideB, agentsDir, analysis, visited, thisKey);
|
|
15368
15838
|
}
|
|
15369
15839
|
}
|
|
15840
|
+
/** Add a hook referenced by an agent or prompt to the packed graph. */
|
|
15841
|
+
async analyzeHook(hookId, agentsDir, analysis, required, parentKey) {
|
|
15842
|
+
const hookFilePath = await this.findFile(path4.join(agentsDir, "hooks"), hookId);
|
|
15843
|
+
if (!hookFilePath) {
|
|
15844
|
+
const message = `Hook file not found for ID: ${hookId}`;
|
|
15845
|
+
if (required) analysis.errors.push(message);
|
|
15846
|
+
else analysis.warnings.push(message);
|
|
15847
|
+
return;
|
|
15848
|
+
}
|
|
15849
|
+
if (!analysis.constituents.hooks.some(
|
|
15850
|
+
(hook) => hook.name === hookId && hook.parentKey === parentKey
|
|
15851
|
+
)) {
|
|
15852
|
+
analysis.constituents.hooks.push({
|
|
15853
|
+
name: hookId,
|
|
15854
|
+
filePath: hookFilePath,
|
|
15855
|
+
discoveredVia: "static",
|
|
15856
|
+
sharedWith: [],
|
|
15857
|
+
parentKey
|
|
15858
|
+
});
|
|
15859
|
+
}
|
|
15860
|
+
}
|
|
15370
15861
|
/**
|
|
15371
15862
|
* Analyze a model and its fallbacks.
|
|
15372
15863
|
*/
|
|
@@ -15501,11 +15992,17 @@ var init_packing_service = __esm({
|
|
|
15501
15992
|
} = options;
|
|
15502
15993
|
const finalPackageName = packageName || packageId;
|
|
15503
15994
|
const packedAt = Date.now();
|
|
15995
|
+
const entryAgentFile = await this.findFile(
|
|
15996
|
+
path4.join(rootDir, "agents", "agents"),
|
|
15997
|
+
agentName
|
|
15998
|
+
);
|
|
15999
|
+
const entryParentHooks = entryAgentFile ? (await extractAgentHooks(fs4.readFileSync(entryAgentFile, "utf-8"))).parentHookRequirements : [];
|
|
15504
16000
|
const meta = {
|
|
15505
16001
|
packageId,
|
|
15506
16002
|
version,
|
|
15507
16003
|
entryAgents: [agentName],
|
|
15508
|
-
packedAt
|
|
16004
|
+
packedAt,
|
|
16005
|
+
...entryParentHooks.length > 0 ? { parentHooks: { [agentName]: entryParentHooks } } : {}
|
|
15509
16006
|
};
|
|
15510
16007
|
const result = {
|
|
15511
16008
|
success: false,
|
|
@@ -15614,6 +16111,7 @@ var init_packing_service = __esm({
|
|
|
15614
16111
|
agentName,
|
|
15615
16112
|
this.deduplicateConstituents(analysis).effects.map((effect) => effect.name),
|
|
15616
16113
|
this.deduplicateConstituents(analysis).threadEndpoints.map((endpoint) => endpoint.name),
|
|
16114
|
+
meta.parentHooks,
|
|
15617
16115
|
externalDeps,
|
|
15618
16116
|
rootDir,
|
|
15619
16117
|
license,
|
|
@@ -16005,7 +16503,7 @@ var init_packing_service = __esm({
|
|
|
16005
16503
|
/**
|
|
16006
16504
|
* Generate the package.json file with dependencies.
|
|
16007
16505
|
*/
|
|
16008
|
-
generatePackageJson(packageName, version, agentName, effects, threadEndpoints, externalDeps, rootDir, license, licenseOwner) {
|
|
16506
|
+
generatePackageJson(packageName, version, agentName, effects, threadEndpoints, parentHooks, externalDeps, rootDir, license, licenseOwner) {
|
|
16009
16507
|
const dependencies = {
|
|
16010
16508
|
"@standardagents/spec": this.resolvePackageVersion("@standardagents/spec", rootDir)
|
|
16011
16509
|
};
|
|
@@ -16027,6 +16525,7 @@ var init_packing_service = __esm({
|
|
|
16027
16525
|
keywords: ["standardagent"],
|
|
16028
16526
|
standardagent: {
|
|
16029
16527
|
entryAgents: [agentName],
|
|
16528
|
+
...parentHooks ? { parentHooks } : {},
|
|
16030
16529
|
...effects.length > 0 ? { effects } : {},
|
|
16031
16530
|
...threadEndpoints.length > 0 ? { threadEndpoints } : {}
|
|
16032
16531
|
},
|
|
@@ -16322,6 +16821,22 @@ ${license || "See LICENSE file"}
|
|
|
16322
16821
|
};
|
|
16323
16822
|
}
|
|
16324
16823
|
});
|
|
16824
|
+
function validParentHooks(value) {
|
|
16825
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
16826
|
+
return Object.values(value).every((requirements) => {
|
|
16827
|
+
if (!Array.isArray(requirements)) return false;
|
|
16828
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16829
|
+
return requirements.every((requirement) => {
|
|
16830
|
+
if (typeof requirement !== "object" || requirement === null) return false;
|
|
16831
|
+
const item = requirement;
|
|
16832
|
+
if (typeof item.hook !== "string" || !item.hook.trim() || typeof item.reason !== "string" || !item.reason.trim() || item.stage !== void 0 && item.stage !== "before_parent" && item.stage !== "after_parent" || seen.has(item.hook)) {
|
|
16833
|
+
return false;
|
|
16834
|
+
}
|
|
16835
|
+
seen.add(item.hook);
|
|
16836
|
+
return true;
|
|
16837
|
+
});
|
|
16838
|
+
});
|
|
16839
|
+
}
|
|
16325
16840
|
var PackageDiscoveryService;
|
|
16326
16841
|
var init_discovery = __esm({
|
|
16327
16842
|
"src/packing/discovery.ts"() {
|
|
@@ -16420,6 +16935,7 @@ var init_discovery = __esm({
|
|
|
16420
16935
|
}
|
|
16421
16936
|
const effects = Array.isArray(pkgJson.standardagent.effects) && pkgJson.standardagent.effects.every((effectName) => typeof effectName === "string") ? pkgJson.standardagent.effects : void 0;
|
|
16422
16937
|
const threadEndpoints = Array.isArray(pkgJson.standardagent.threadEndpoints) && pkgJson.standardagent.threadEndpoints.every((endpoint) => typeof endpoint === "string") ? pkgJson.standardagent.threadEndpoints : void 0;
|
|
16938
|
+
const parentHooks = validParentHooks(pkgJson.standardagent.parentHooks) ? pkgJson.standardagent.parentHooks : void 0;
|
|
16423
16939
|
return {
|
|
16424
16940
|
packageId: pkgJson.name || pkgName,
|
|
16425
16941
|
version: pkgJson.version || "0.0.0",
|
|
@@ -16428,6 +16944,7 @@ var init_discovery = __esm({
|
|
|
16428
16944
|
entryAgents: pkgJson.standardagent.entryAgents,
|
|
16429
16945
|
...effects ? { effects } : {},
|
|
16430
16946
|
...threadEndpoints ? { threadEndpoints } : {},
|
|
16947
|
+
...parentHooks ? { parentHooks } : {},
|
|
16431
16948
|
description: pkgJson.description
|
|
16432
16949
|
};
|
|
16433
16950
|
} catch (error) {
|
|
@@ -16489,6 +17006,7 @@ var init_discovery = __esm({
|
|
|
16489
17006
|
}
|
|
16490
17007
|
const effects = Array.isArray(pkgJson.standardagent.effects) && pkgJson.standardagent.effects.every((effectName) => typeof effectName === "string") ? pkgJson.standardagent.effects : void 0;
|
|
16491
17008
|
const threadEndpoints = Array.isArray(pkgJson.standardagent.threadEndpoints) && pkgJson.standardagent.threadEndpoints.every((endpoint) => typeof endpoint === "string") ? pkgJson.standardagent.threadEndpoints : void 0;
|
|
17009
|
+
const parentHooks = validParentHooks(pkgJson.standardagent.parentHooks) ? pkgJson.standardagent.parentHooks : void 0;
|
|
16492
17010
|
return {
|
|
16493
17011
|
packageId: pkgJson.name || dirName,
|
|
16494
17012
|
version: pkgJson.version || "0.0.0",
|
|
@@ -16497,6 +17015,7 @@ var init_discovery = __esm({
|
|
|
16497
17015
|
entryAgents: pkgJson.standardagent.entryAgents,
|
|
16498
17016
|
...effects ? { effects } : {},
|
|
16499
17017
|
...threadEndpoints ? { threadEndpoints } : {},
|
|
17018
|
+
...parentHooks ? { parentHooks } : {},
|
|
16500
17019
|
description: pkgJson.description
|
|
16501
17020
|
};
|
|
16502
17021
|
} catch (error) {
|
|
@@ -16525,7 +17044,8 @@ var init_discovery = __esm({
|
|
|
16525
17044
|
const hasValidEntryAgents = Array.isArray(f.entryAgents) && f.entryAgents.length > 0 && f.entryAgents.every((e) => typeof e === "string");
|
|
16526
17045
|
const hasValidEffects = f.effects === void 0 || Array.isArray(f.effects) && f.effects.every((effectName) => typeof effectName === "string");
|
|
16527
17046
|
const hasValidThreadEndpoints = f.threadEndpoints === void 0 || Array.isArray(f.threadEndpoints) && f.threadEndpoints.every((endpoint) => typeof endpoint === "string");
|
|
16528
|
-
|
|
17047
|
+
const hasValidParentHooks = f.parentHooks === void 0 || validParentHooks(f.parentHooks);
|
|
17048
|
+
return hasValidEntryAgents && hasValidEffects && hasValidThreadEndpoints && hasValidParentHooks;
|
|
16529
17049
|
}
|
|
16530
17050
|
/**
|
|
16531
17051
|
* Get a package by ID.
|
|
@@ -67824,8 +68344,10 @@ var agents_get_default = defineController2(async ({ agents, agentNames, registry
|
|
|
67824
68344
|
title: definition.title || definition.name,
|
|
67825
68345
|
type: definition.type || "ai_human",
|
|
67826
68346
|
description: definition.description || null,
|
|
68347
|
+
tool_description: definition.toolDescription || null,
|
|
67827
68348
|
icon: definition.icon || null,
|
|
67828
68349
|
primary: definition.primary !== false,
|
|
68350
|
+
parentHooks: definition.parentHooks || [],
|
|
67829
68351
|
...includeAuthoringDetails ? {
|
|
67830
68352
|
default_prompt: definition.sideA?.prompt || "",
|
|
67831
68353
|
default_model: "",
|
|
@@ -67861,8 +68383,10 @@ var agents_get_default = defineController2(async ({ agents, agentNames, registry
|
|
|
67861
68383
|
title: definition.title || definition.name,
|
|
67862
68384
|
type: definition.type || "ai_human",
|
|
67863
68385
|
description: definition.description || null,
|
|
68386
|
+
tool_description: definition.toolDescription || null,
|
|
67864
68387
|
icon: definition.icon || null,
|
|
67865
68388
|
primary: definition.primary !== false,
|
|
68389
|
+
parentHooks: definition.parentHooks || [],
|
|
67866
68390
|
...includeAuthoringDetails ? {
|
|
67867
68391
|
default_prompt: definition.sideA?.prompt || "",
|
|
67868
68392
|
default_model: "",
|
|
@@ -68370,7 +68894,7 @@ var config_get_default = defineController2(async ({ config, env: env2, req }) =>
|
|
|
68370
68894
|
});
|
|
68371
68895
|
|
|
68372
68896
|
// src/version.ts
|
|
68373
|
-
var BUILDER_VERSION = "0.
|
|
68897
|
+
var BUILDER_VERSION = "0.40.0".length > 0 ? "0.40.0" : "dev";
|
|
68374
68898
|
|
|
68375
68899
|
// src/api/diagnostics.get.ts
|
|
68376
68900
|
init_LLMRequest();
|
|
@@ -69743,8 +70267,10 @@ migrations.reduce(
|
|
|
69743
70267
|
);
|
|
69744
70268
|
|
|
69745
70269
|
// src/durable-objects/DurableAgentBuilder.ts
|
|
70270
|
+
init_resolver();
|
|
69746
70271
|
init_types();
|
|
69747
70272
|
init_scope();
|
|
70273
|
+
init_ParentHookResolver();
|
|
69748
70274
|
var THREAD_PREVIEW_MAX_CHARS = 140;
|
|
69749
70275
|
var buildThreadPreview = (content) => {
|
|
69750
70276
|
const collapsed = content.replace(/\s+/g, " ").trim();
|
|
@@ -70271,6 +70797,7 @@ var name_get_default = defineController2(async ({ params, agents, prompts, promp
|
|
|
70271
70797
|
expose_as_tool: definition.exposeAsTool || false,
|
|
70272
70798
|
primary: definition.primary !== false,
|
|
70273
70799
|
tool_description: definition.toolDescription || null,
|
|
70800
|
+
parent_hooks: definition.parentHooks || [],
|
|
70274
70801
|
env: agentEnv,
|
|
70275
70802
|
tenvs: agentEnv,
|
|
70276
70803
|
// deprecated alias
|