@standardagents/builder 0.39.1 → 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.
Files changed (42) hide show
  1. package/dist/built-in-routes.js +494 -78
  2. package/dist/built-in-routes.js.map +1 -1
  3. package/dist/client/{ApiKeysView-AH5i-H6j.js → ApiKeysView-DoYvZZ7e.js} +1 -1
  4. package/dist/client/{CenteredContentView-DaBp0K-A.js → CenteredContentView-53PY0cqY.js} +1 -1
  5. package/dist/client/{CompositionView-yY1Q4M23.js → CompositionView-fp-0YnPt.js} +1 -1
  6. 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
  7. 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
  8. 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
  9. package/dist/client/{JsonViewer-Bi8Zdmir.js → JsonViewer-6aaGzutE.js} +1 -1
  10. package/dist/client/{LoginView-BIKahEU6.js → LoginView-DwpCmNw9.js} +1 -1
  11. package/dist/client/{MarketplaceView-DPDPVH68.js → MarketplaceView-Da02L0J5.js} +1 -1
  12. 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
  13. 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
  14. package/dist/client/{ModelsView-Q2WXu1Gw.js → ModelsView-BLlHO9Ud.js} +1 -1
  15. package/dist/client/{PromptEditView-BzA-3n1w.js → PromptEditView-EeNwTDtT.js} +1 -1
  16. package/dist/client/{PromptModal-CJWh_cru.js → PromptModal-BkwrKJ2d.js} +1 -1
  17. package/dist/client/{PromptsView-BezNl-Et.js → PromptsView-D1r7tsLu.js} +1 -1
  18. package/dist/client/{ProvidersView-BuzSKxuT.js → ProvidersView-CmUDl5nM.js} +1 -1
  19. 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
  20. package/dist/client/{ThreadsView-DPCpZA4J.js → ThreadsView-Bl5fSIO1.js} +1 -1
  21. package/dist/client/{ToolsView-DMjFMAhH.js → ToolsView-DlVEF8-7.js} +1 -1
  22. package/dist/client/{UsersView-B7jXLNQs.js → UsersView-CGlA7a7R.js} +1 -1
  23. package/dist/client/{VariablesView-CF7x0G8g.js → VariablesView-BpYmJL4V.js} +1 -1
  24. package/dist/client/index-CKtIkI0N.js +6 -0
  25. package/dist/client/index.html +1 -1
  26. package/dist/{discovery-DiMJWisl.d.ts → discovery-DZ7fv-b4.d.ts} +3 -2
  27. package/dist/{index-yIcqf7DC.d.ts → index-9MaIifn3.d.ts} +7 -2
  28. package/dist/index.d.ts +4 -4
  29. package/dist/index.js +1242 -762
  30. package/dist/index.js.map +1 -1
  31. package/dist/packing.d.ts +5 -3
  32. package/dist/packing.js +180 -5
  33. package/dist/packing.js.map +1 -1
  34. package/dist/plugin.js +252 -17
  35. package/dist/plugin.js.map +1 -1
  36. package/dist/runtime.d.ts +10 -5
  37. package/dist/runtime.js +993 -750
  38. package/dist/runtime.js.map +1 -1
  39. package/dist/test.d.ts +2 -2
  40. package/dist/{types-Bpe7IANZ.d.ts → types-BMnBYNwn.d.ts} +3 -1
  41. package/package.json +5 -5
  42. package/dist/client/index-eGECJFYe.js +0 -6
@@ -6680,6 +6680,255 @@ var init_context = __esm({
6680
6680
  }
6681
6681
  });
6682
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
+
6683
6932
  // src/agents/FlowEngine.ts
6684
6933
  var FlowEngine_exports = {};
6685
6934
  __export(FlowEngine_exports, {
@@ -6696,6 +6945,7 @@ var init_FlowEngine = __esm({
6696
6945
  init_context();
6697
6946
  init_sessionTools();
6698
6947
  init_ThreadStateImpl();
6948
+ init_ParentHookResolver();
6699
6949
  IMMEDIATE_BOOTSTRAP_TOOL_NAME = "bootstrap_immediate_subagent";
6700
6950
  HookBlockedExecutionError = class extends Error {
6701
6951
  constructor(message) {
@@ -7038,7 +7288,8 @@ This usually points to something I can't fix from here \u2014 for example the wo
7038
7288
  _variables: def.variables ?? [],
7039
7289
  _env: def.env ?? def.tenvs ?? {},
7040
7290
  _requiredSchema: def.requiredSchema ?? null,
7041
- _hooks: def.hooks ?? []
7291
+ _hooks: def.hooks ?? [],
7292
+ _package: def.__package
7042
7293
  };
7043
7294
  }
7044
7295
  /**
@@ -7428,6 +7679,8 @@ This usually points to something I can't fix from here \u2014 for example the wo
7428
7679
  type: newAgentDef.type,
7429
7680
  created_at: Date.now(),
7430
7681
  max_session_turns: newAgentDef.maxSessionTurns ?? null,
7682
+ hooks: newAgentDef.hooks ?? [],
7683
+ _package: newAgentDef.__package,
7431
7684
  side_a_label: newAgentDef.sideA?.label ?? null,
7432
7685
  side_a_agent_prompt: newAgentDef.sideA?.prompt ?? null,
7433
7686
  side_a_stop_on_response: newAgentDef.sideA?.stopOnResponse ?? true,
@@ -7588,7 +7841,7 @@ This usually points to something I can't fix from here \u2014 for example the wo
7588
7841
  return null;
7589
7842
  }
7590
7843
  return await stub.resolveThreadEnv({
7591
- threadId: state.threadId,
7844
+ threadId: state.thread.metadata.id,
7592
7845
  property,
7593
7846
  promptName: state.prompt?.name
7594
7847
  });
@@ -8110,8 +8363,8 @@ This usually points to something I can't fix from here \u2014 for example the wo
8110
8363
  state.context[key] = existing;
8111
8364
  }
8112
8365
  static async runImmediateToolsIfNeeded(state) {
8113
- const promptTools = Array.isArray(state.prompt._tools) ? state.prompt._tools : [];
8114
- if (promptTools.length === 0) {
8366
+ const promptTools2 = Array.isArray(state.prompt._tools) ? state.prompt._tools : [];
8367
+ if (promptTools2.length === 0) {
8115
8368
  return false;
8116
8369
  }
8117
8370
  if (!state.immediatePromptRuns) {
@@ -8147,7 +8400,7 @@ This usually points to something I can't fix from here \u2014 for example the wo
8147
8400
  (activeInstanceCounts.get(child.name) ?? 0) + 1
8148
8401
  );
8149
8402
  }
8150
- for (const toolConfig of promptTools) {
8403
+ for (const toolConfig of promptTools2) {
8151
8404
  if (!toolConfig || typeof toolConfig !== "object") {
8152
8405
  continue;
8153
8406
  }
@@ -8313,10 +8566,10 @@ This usually points to something I can't fix from here \u2014 for example the wo
8313
8566
  * model's to clean up, and terminate_subagent on an infrastructure child
8314
8567
  * kills work the runtime depends on. Static and pure for direct testing.
8315
8568
  */
8316
- static filterModelVisibleSubagents(registry, promptTools) {
8569
+ static filterModelVisibleSubagents(registry, promptTools2) {
8317
8570
  if (registry.length === 0) return registry;
8318
8571
  const hidden = /* @__PURE__ */ new Set();
8319
- for (const config of promptTools ?? []) {
8572
+ for (const config of promptTools2 ?? []) {
8320
8573
  if (typeof config === "object" && config !== null && "name" in config && config.hidden === true) {
8321
8574
  hidden.add(config.name);
8322
8575
  }
@@ -9346,8 +9599,8 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9346
9599
  try {
9347
9600
  const nativeTools = await this.loadNativeTools(state);
9348
9601
  tools.push(...nativeTools);
9349
- const promptTools = await this.loadPromptTools(state);
9350
- tools.push(...promptTools);
9602
+ const promptTools2 = await this.loadPromptTools(state);
9603
+ tools.push(...promptTools2);
9351
9604
  const agentTools = await this.loadAgentTools(state);
9352
9605
  tools.push(...agentTools);
9353
9606
  const toolNameSources = /* @__PURE__ */ new Map();
@@ -9356,7 +9609,7 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9356
9609
  sources.add("native tool");
9357
9610
  toolNameSources.set(tool3.function.name, sources);
9358
9611
  }
9359
- for (const tool3 of promptTools) {
9612
+ for (const tool3 of promptTools2) {
9360
9613
  const sources = toolNameSources.get(tool3.function.name) || /* @__PURE__ */ new Set();
9361
9614
  sources.add("prompt");
9362
9615
  toolNameSources.set(tool3.function.name, sources);
@@ -9498,24 +9751,8 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9498
9751
  // Hook Resolution Helpers
9499
9752
  // ==========================================================================
9500
9753
  /**
9501
- * Get the list of hook IDs that should run for the current context.
9502
- * Resolution: prompt hooks > agent hooks > empty array
9503
- *
9504
- * @param state - Flow state with prompt and agent configuration
9505
- * @returns Array of hook IDs to execute
9506
- */
9507
- static getActiveHookIds(state) {
9508
- if (state.prompt?._hooks !== void 0 && state.prompt._hooks.length > 0) {
9509
- return state.prompt._hooks;
9510
- }
9511
- if (state.agentConfig.hooks !== void 0 && state.agentConfig.hooks.length > 0) {
9512
- return state.agentConfig.hooks;
9513
- }
9514
- return [];
9515
- }
9516
- /**
9517
- * Get hooks of a specific type from the active hook IDs.
9518
- * 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.
9519
9756
  *
9520
9757
  * @template K - The hook type name (ensures type-safe executors)
9521
9758
  * @param state - Flow state with hook configuration
@@ -9523,24 +9760,17 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9523
9760
  * @returns Array of typed hook executor functions
9524
9761
  */
9525
9762
  static async getHooksForType(state, hookType) {
9526
- const hookIds = this.getActiveHookIds(state);
9527
- if (hookIds.length === 0) return [];
9528
- const hooksRegistry = state.thread.instance.hooks();
9529
- if (!hooksRegistry) return [];
9530
- const executors = [];
9531
- for (const hookId of hookIds) {
9532
- const hookLoader = hooksRegistry[hookId];
9533
- if (!hookLoader) continue;
9534
- try {
9535
- const hookDef = await hookLoader();
9536
- if (hookDef && hookDef.hook === hookType) {
9537
- executors.push(hookDef.execute);
9538
- }
9539
- } catch (error) {
9540
- console.error(`[Hooks] Failed to load hook '${hookId}':`, error);
9541
- }
9542
- }
9543
- 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
+ );
9544
9774
  }
9545
9775
  // ==========================================================================
9546
9776
  // Hook Runner Methods
@@ -9558,9 +9788,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9558
9788
  if (executors.length === 0) return messages;
9559
9789
  let result = messages;
9560
9790
  const threadState = ThreadStateImpl.fromFlowState(state);
9561
- for (const executor of executors) {
9791
+ for (const { execute, context } of executors) {
9562
9792
  try {
9563
- result = await executor(threadState, result);
9793
+ result = await execute(threadState, result, context);
9564
9794
  } catch (error) {
9565
9795
  if (error && typeof error === "object" && error.block === true) {
9566
9796
  throw new HookBlockedExecutionError(error instanceof Error ? error.message : String(error));
@@ -9578,9 +9808,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9578
9808
  if (executors.length === 0) return systemMessage;
9579
9809
  let result = systemMessage;
9580
9810
  const threadState = ThreadStateImpl.fromFlowState(state);
9581
- for (const executor of executors) {
9811
+ for (const { execute, context } of executors) {
9582
9812
  try {
9583
- const next = await executor(threadState, result);
9813
+ const next = await execute(threadState, result, context);
9584
9814
  if (next !== null && next !== void 0) {
9585
9815
  result = next;
9586
9816
  }
@@ -9597,9 +9827,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9597
9827
  const executors = await this.getHooksForType(state, "after_subagent_created");
9598
9828
  if (executors.length === 0) return;
9599
9829
  const threadState = ThreadStateImpl.fromFlowState(state);
9600
- for (const executor of executors) {
9830
+ for (const { execute, context } of executors) {
9601
9831
  try {
9602
- await executor(threadState, childState);
9832
+ await execute(threadState, childState, context);
9603
9833
  } catch (error) {
9604
9834
  console.error("[Hooks] \u2717 Error running after_subagent_created hook:", error);
9605
9835
  }
@@ -9618,9 +9848,13 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9618
9848
  if (executors.length === 0) return message;
9619
9849
  let result = message;
9620
9850
  const threadState = threadStateOverride ?? ThreadStateImpl.fromFlowState(state);
9621
- for (const executor of executors) {
9851
+ for (const { execute, context } of executors) {
9622
9852
  try {
9623
- const hooked = await executor(threadState, _FlowEngine.rowToHookMessage(result));
9853
+ const hooked = await execute(
9854
+ threadState,
9855
+ _FlowEngine.rowToHookMessage(result),
9856
+ context
9857
+ );
9624
9858
  result = {
9625
9859
  ...result,
9626
9860
  ...hooked,
@@ -9646,9 +9880,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9646
9880
  const executors = await this.getHooksForType(state, "after_create_message");
9647
9881
  if (executors.length === 0) return;
9648
9882
  const threadState = threadStateOverride ?? ThreadStateImpl.fromFlowState(state);
9649
- for (const executor of executors) {
9883
+ for (const { execute, context } of executors) {
9650
9884
  try {
9651
- await executor(threadState, _FlowEngine.rowToHookMessage(message));
9885
+ await execute(threadState, _FlowEngine.rowToHookMessage(message), context);
9652
9886
  } catch (error) {
9653
9887
  console.error("[Hooks] \u2717 Error running after_create_message hook:", error);
9654
9888
  }
@@ -9689,9 +9923,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9689
9923
  if (executors.length === 0) return updates;
9690
9924
  let result = updates;
9691
9925
  const threadState = ThreadStateImpl.fromFlowState(state);
9692
- for (const executor of executors) {
9926
+ for (const { execute, context } of executors) {
9693
9927
  try {
9694
- result = await executor(threadState, messageId, result);
9928
+ result = await execute(threadState, messageId, result, context);
9695
9929
  } catch (error) {
9696
9930
  console.error("[Hooks] \u2717 Error running before_update_message hook:", error);
9697
9931
  }
@@ -9709,9 +9943,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9709
9943
  const executors = await this.getHooksForType(state, "after_update_message");
9710
9944
  if (executors.length === 0) return;
9711
9945
  const threadState = ThreadStateImpl.fromFlowState(state);
9712
- for (const executor of executors) {
9946
+ for (const { execute, context } of executors) {
9713
9947
  try {
9714
- await executor(threadState, _FlowEngine.rowToHookMessage(message));
9948
+ await execute(threadState, _FlowEngine.rowToHookMessage(message), context);
9715
9949
  } catch (error) {
9716
9950
  console.error("[Hooks] \u2717 Error running after_update_message hook:", error);
9717
9951
  }
@@ -9731,9 +9965,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9731
9965
  if (executors.length === 0) return toolResult;
9732
9966
  let result = toolResult;
9733
9967
  const threadState = ThreadStateImpl.fromFlowState(state);
9734
- for (const executor of executors) {
9968
+ for (const { execute, context } of executors) {
9735
9969
  try {
9736
- result = await executor(threadState, toolCall, result);
9970
+ result = await execute(threadState, toolCall, result, context);
9737
9971
  } catch (error) {
9738
9972
  console.error("[Hooks] \u2717 Error running before_store_tool_result hook:", error);
9739
9973
  }
@@ -9753,10 +9987,10 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9753
9987
  if (executors.length === 0) return toolResult;
9754
9988
  let result = toolResult;
9755
9989
  const threadState = ThreadStateImpl.fromFlowState(state);
9756
- for (const executor of executors) {
9990
+ for (const { execute, context } of executors) {
9757
9991
  if (result === null) break;
9758
9992
  try {
9759
- result = await executor(threadState, toolCall, result);
9993
+ result = await execute(threadState, toolCall, result, context);
9760
9994
  } catch (error) {
9761
9995
  console.error("[Hooks] \u2717 Error running after_tool_call_success hook:", error);
9762
9996
  }
@@ -9776,10 +10010,10 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9776
10010
  if (executors.length === 0) return toolResult;
9777
10011
  let result = toolResult;
9778
10012
  const threadState = ThreadStateImpl.fromFlowState(state);
9779
- for (const executor of executors) {
10013
+ for (const { execute, context } of executors) {
9780
10014
  if (result === null) break;
9781
10015
  try {
9782
- result = await executor(threadState, toolCall, result);
10016
+ result = await execute(threadState, toolCall, result, context);
9783
10017
  } catch (error) {
9784
10018
  console.error("[Hooks] \u2717 Error running after_tool_call_failure hook:", error);
9785
10019
  }
@@ -9809,9 +10043,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9809
10043
  const executors = await this.getHooksForType(state, "tool_call_started");
9810
10044
  if (executors.length === 0) return;
9811
10045
  const threadState = ThreadStateImpl.fromFlowState(state);
9812
- for (const executor of executors) {
10046
+ for (const { execute, context } of executors) {
9813
10047
  try {
9814
- await executor(threadState, toolCall, progress);
10048
+ await execute(threadState, toolCall, progress, context);
9815
10049
  } catch (error) {
9816
10050
  console.error("[Hooks] \u2717 Error running tool_call_started hook:", error);
9817
10051
  }
@@ -9839,9 +10073,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
9839
10073
  const executors = await this.getHooksForType(state, "tool_call_done");
9840
10074
  if (executors.length === 0) return;
9841
10075
  const threadState = ThreadStateImpl.fromFlowState(state);
9842
- for (const executor of executors) {
10076
+ for (const { execute, context } of executors) {
9843
10077
  try {
9844
- await executor(threadState, toolCall, toolResult);
10078
+ await execute(threadState, toolCall, toolResult, context);
9845
10079
  } catch (error) {
9846
10080
  console.error("[Hooks] \u2717 Error running tool_call_done hook:", error);
9847
10081
  }
@@ -10794,12 +11028,12 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
10794
11028
  if (executors.length === 0) return messages;
10795
11029
  let result = messages;
10796
11030
  const threadState = ThreadStateImpl.fromFlowState(state);
10797
- for (const executor of executors) {
11031
+ for (const { execute, context } of executors) {
10798
11032
  try {
10799
11033
  const byId = /* @__PURE__ */ new Map();
10800
11034
  for (const row of result) if (row.id) byId.set(row.id, row);
10801
11035
  const hookView = result.map((row) => _FlowEngine.rowToHookMessage(row));
10802
- const kept = await executor(threadState, hookView);
11036
+ const kept = await execute(threadState, hookView, context);
10803
11037
  result = kept.map((hookedMessage) => {
10804
11038
  const original = hookedMessage.id ? byId.get(hookedMessage.id) : void 0;
10805
11039
  if (original) {
@@ -14803,11 +15037,19 @@ async function extractPromptTools(sourceCode) {
14803
15037
  result.tools.push(element.text);
14804
15038
  } else if (ts.isObjectLiteralExpression(element)) {
14805
15039
  result.hasSubpromptConfigs = true;
15040
+ let configuredName;
15041
+ let implementingAgent;
14806
15042
  for (const objProp of element.properties) {
14807
- if (ts.isPropertyAssignment(objProp) && ts.isIdentifier(objProp.name) && objProp.name.text === "name" && ts.isStringLiteral(objProp.initializer)) {
14808
- result.tools.push(objProp.initializer.text);
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
+ }
14809
15049
  }
14810
15050
  }
15051
+ const dependencyName = implementingAgent ?? configuredName;
15052
+ if (dependencyName) result.tools.push(dependencyName);
14811
15053
  }
14812
15054
  }
14813
15055
  }
@@ -14930,6 +15172,106 @@ async function extractAgentPrompts(sourceCode) {
14930
15172
  visit2(sourceFile);
14931
15173
  return result;
14932
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
+ }
14933
15275
  async function extractAgentDescription(sourceCode) {
14934
15276
  const ts = await loadTypeScript();
14935
15277
  const sourceFile = ts.createSourceFile(
@@ -15185,6 +15527,13 @@ var init_packing_service = __esm({
15185
15527
  });
15186
15528
  const agentSource = fs4.readFileSync(agentFilePath, "utf-8");
15187
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
+ }
15188
15537
  if (agentPrompts.sideA) {
15189
15538
  analysis.primaryPrompt = agentPrompts.sideA;
15190
15539
  await this.analyzePrompt(agentPrompts.sideA, agentsDir, analysis, /* @__PURE__ */ new Set(), `agent:${agentName}`);
@@ -15387,6 +15736,9 @@ var init_packing_service = __esm({
15387
15736
  }
15388
15737
  visited.add(`prompt:${promptName}`);
15389
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
+ }
15390
15742
  const modelName = await extractPromptModel(promptSource);
15391
15743
  if (modelName) {
15392
15744
  await this.analyzeModel(modelName, agentsDir, analysis, visited, thisKey);
@@ -15471,6 +15823,13 @@ var init_packing_service = __esm({
15471
15823
  visited.add(`agent:${agentName}`);
15472
15824
  const agentSource = fs4.readFileSync(agentFilePath, "utf-8");
15473
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
+ }
15474
15833
  if (agentPrompts.sideA) {
15475
15834
  await this.analyzePrompt(agentPrompts.sideA, agentsDir, analysis, visited, thisKey);
15476
15835
  }
@@ -15478,6 +15837,27 @@ var init_packing_service = __esm({
15478
15837
  await this.analyzePrompt(agentPrompts.sideB, agentsDir, analysis, visited, thisKey);
15479
15838
  }
15480
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
+ }
15481
15861
  /**
15482
15862
  * Analyze a model and its fallbacks.
15483
15863
  */
@@ -15612,11 +15992,17 @@ var init_packing_service = __esm({
15612
15992
  } = options;
15613
15993
  const finalPackageName = packageName || packageId;
15614
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 : [];
15615
16000
  const meta = {
15616
16001
  packageId,
15617
16002
  version,
15618
16003
  entryAgents: [agentName],
15619
- packedAt
16004
+ packedAt,
16005
+ ...entryParentHooks.length > 0 ? { parentHooks: { [agentName]: entryParentHooks } } : {}
15620
16006
  };
15621
16007
  const result = {
15622
16008
  success: false,
@@ -15725,6 +16111,7 @@ var init_packing_service = __esm({
15725
16111
  agentName,
15726
16112
  this.deduplicateConstituents(analysis).effects.map((effect) => effect.name),
15727
16113
  this.deduplicateConstituents(analysis).threadEndpoints.map((endpoint) => endpoint.name),
16114
+ meta.parentHooks,
15728
16115
  externalDeps,
15729
16116
  rootDir,
15730
16117
  license,
@@ -16116,7 +16503,7 @@ var init_packing_service = __esm({
16116
16503
  /**
16117
16504
  * Generate the package.json file with dependencies.
16118
16505
  */
16119
- generatePackageJson(packageName, version, agentName, effects, threadEndpoints, externalDeps, rootDir, license, licenseOwner) {
16506
+ generatePackageJson(packageName, version, agentName, effects, threadEndpoints, parentHooks, externalDeps, rootDir, license, licenseOwner) {
16120
16507
  const dependencies = {
16121
16508
  "@standardagents/spec": this.resolvePackageVersion("@standardagents/spec", rootDir)
16122
16509
  };
@@ -16138,6 +16525,7 @@ var init_packing_service = __esm({
16138
16525
  keywords: ["standardagent"],
16139
16526
  standardagent: {
16140
16527
  entryAgents: [agentName],
16528
+ ...parentHooks ? { parentHooks } : {},
16141
16529
  ...effects.length > 0 ? { effects } : {},
16142
16530
  ...threadEndpoints.length > 0 ? { threadEndpoints } : {}
16143
16531
  },
@@ -16433,6 +16821,22 @@ ${license || "See LICENSE file"}
16433
16821
  };
16434
16822
  }
16435
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
+ }
16436
16840
  var PackageDiscoveryService;
16437
16841
  var init_discovery = __esm({
16438
16842
  "src/packing/discovery.ts"() {
@@ -16531,6 +16935,7 @@ var init_discovery = __esm({
16531
16935
  }
16532
16936
  const effects = Array.isArray(pkgJson.standardagent.effects) && pkgJson.standardagent.effects.every((effectName) => typeof effectName === "string") ? pkgJson.standardagent.effects : void 0;
16533
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;
16534
16939
  return {
16535
16940
  packageId: pkgJson.name || pkgName,
16536
16941
  version: pkgJson.version || "0.0.0",
@@ -16539,6 +16944,7 @@ var init_discovery = __esm({
16539
16944
  entryAgents: pkgJson.standardagent.entryAgents,
16540
16945
  ...effects ? { effects } : {},
16541
16946
  ...threadEndpoints ? { threadEndpoints } : {},
16947
+ ...parentHooks ? { parentHooks } : {},
16542
16948
  description: pkgJson.description
16543
16949
  };
16544
16950
  } catch (error) {
@@ -16600,6 +17006,7 @@ var init_discovery = __esm({
16600
17006
  }
16601
17007
  const effects = Array.isArray(pkgJson.standardagent.effects) && pkgJson.standardagent.effects.every((effectName) => typeof effectName === "string") ? pkgJson.standardagent.effects : void 0;
16602
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;
16603
17010
  return {
16604
17011
  packageId: pkgJson.name || dirName,
16605
17012
  version: pkgJson.version || "0.0.0",
@@ -16608,6 +17015,7 @@ var init_discovery = __esm({
16608
17015
  entryAgents: pkgJson.standardagent.entryAgents,
16609
17016
  ...effects ? { effects } : {},
16610
17017
  ...threadEndpoints ? { threadEndpoints } : {},
17018
+ ...parentHooks ? { parentHooks } : {},
16611
17019
  description: pkgJson.description
16612
17020
  };
16613
17021
  } catch (error) {
@@ -16636,7 +17044,8 @@ var init_discovery = __esm({
16636
17044
  const hasValidEntryAgents = Array.isArray(f.entryAgents) && f.entryAgents.length > 0 && f.entryAgents.every((e) => typeof e === "string");
16637
17045
  const hasValidEffects = f.effects === void 0 || Array.isArray(f.effects) && f.effects.every((effectName) => typeof effectName === "string");
16638
17046
  const hasValidThreadEndpoints = f.threadEndpoints === void 0 || Array.isArray(f.threadEndpoints) && f.threadEndpoints.every((endpoint) => typeof endpoint === "string");
16639
- return hasValidEntryAgents && hasValidEffects && hasValidThreadEndpoints;
17047
+ const hasValidParentHooks = f.parentHooks === void 0 || validParentHooks(f.parentHooks);
17048
+ return hasValidEntryAgents && hasValidEffects && hasValidThreadEndpoints && hasValidParentHooks;
16640
17049
  }
16641
17050
  /**
16642
17051
  * Get a package by ID.
@@ -67935,8 +68344,10 @@ var agents_get_default = defineController2(async ({ agents, agentNames, registry
67935
68344
  title: definition.title || definition.name,
67936
68345
  type: definition.type || "ai_human",
67937
68346
  description: definition.description || null,
68347
+ tool_description: definition.toolDescription || null,
67938
68348
  icon: definition.icon || null,
67939
68349
  primary: definition.primary !== false,
68350
+ parentHooks: definition.parentHooks || [],
67940
68351
  ...includeAuthoringDetails ? {
67941
68352
  default_prompt: definition.sideA?.prompt || "",
67942
68353
  default_model: "",
@@ -67972,8 +68383,10 @@ var agents_get_default = defineController2(async ({ agents, agentNames, registry
67972
68383
  title: definition.title || definition.name,
67973
68384
  type: definition.type || "ai_human",
67974
68385
  description: definition.description || null,
68386
+ tool_description: definition.toolDescription || null,
67975
68387
  icon: definition.icon || null,
67976
68388
  primary: definition.primary !== false,
68389
+ parentHooks: definition.parentHooks || [],
67977
68390
  ...includeAuthoringDetails ? {
67978
68391
  default_prompt: definition.sideA?.prompt || "",
67979
68392
  default_model: "",
@@ -68481,7 +68894,7 @@ var config_get_default = defineController2(async ({ config, env: env2, req }) =>
68481
68894
  });
68482
68895
 
68483
68896
  // src/version.ts
68484
- var BUILDER_VERSION = "0.39.1".length > 0 ? "0.39.1" : "dev";
68897
+ var BUILDER_VERSION = "0.40.0".length > 0 ? "0.40.0" : "dev";
68485
68898
 
68486
68899
  // src/api/diagnostics.get.ts
68487
68900
  init_LLMRequest();
@@ -69854,8 +70267,10 @@ migrations.reduce(
69854
70267
  );
69855
70268
 
69856
70269
  // src/durable-objects/DurableAgentBuilder.ts
70270
+ init_resolver();
69857
70271
  init_types();
69858
70272
  init_scope();
70273
+ init_ParentHookResolver();
69859
70274
  var THREAD_PREVIEW_MAX_CHARS = 140;
69860
70275
  var buildThreadPreview = (content) => {
69861
70276
  const collapsed = content.replace(/\s+/g, " ").trim();
@@ -70382,6 +70797,7 @@ var name_get_default = defineController2(async ({ params, agents, prompts, promp
70382
70797
  expose_as_tool: definition.exposeAsTool || false,
70383
70798
  primary: definition.primary !== false,
70384
70799
  tool_description: definition.toolDescription || null,
70800
+ parent_hooks: definition.parentHooks || [],
70385
70801
  env: agentEnv,
70386
70802
  tenvs: agentEnv,
70387
70803
  // deprecated alias