@cuylabs/agent-core 0.8.0 → 0.9.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 (68) hide show
  1. package/dist/{builder-UpOWQMW3.d.ts → builder-BgZ_j4Vs.d.ts} +2 -1
  2. package/dist/{chunk-RZITT45F.js → chunk-4QFNWPIF.js} +4 -4
  3. package/dist/{chunk-BFM2YHNM.js → chunk-5ARZJWD2.js} +74 -37
  4. package/dist/{chunk-KUVSERLJ.js → chunk-DXFBQMXP.js} +5 -2
  5. package/dist/{chunk-CAA7FHIH.js → chunk-EKR6PKXU.js} +0 -100
  6. package/dist/{chunk-IVUJDISU.js → chunk-GFTW23FV.js} +5 -14
  7. package/dist/{chunk-7VKQ4WPB.js → chunk-H3FUYU52.js} +11 -3
  8. package/dist/chunk-I6PKJ7XQ.js +292 -0
  9. package/dist/chunk-IYWQOJMQ.js +102 -0
  10. package/dist/{chunk-4BDA7DQY.js → chunk-J4QDGZIA.js} +19 -3
  11. package/dist/{chunk-7MUFEN4K.js → chunk-JLXG2SH7.js} +349 -3
  12. package/dist/{chunk-YSLSEQ6B.js → chunk-MAZ5DY5B.js} +18 -30
  13. package/dist/{chunk-P6YF7USR.js → chunk-MHKK374K.js} +12 -11
  14. package/dist/{chunk-VBWWUHWI.js → chunk-OFDKHNCX.js} +4 -1
  15. package/dist/{chunk-YUUJK53A.js → chunk-RKEW5WXI.js} +1 -1
  16. package/dist/{chunk-LRHOS4ZN.js → chunk-SPILYYDF.js} +3 -2
  17. package/dist/{chunk-RFEKJKTO.js → chunk-UDCZ673N.js} +321 -275
  18. package/dist/{chunk-BDBZ3SLK.js → chunk-UHCJEM2E.js} +39 -2
  19. package/dist/chunk-WGZAPU6N.js +929 -0
  20. package/dist/{chunk-N6HWIEEA.js → chunk-WKHDSSXG.js} +140 -23
  21. package/dist/index-BCqEGzBj.d.ts +251 -0
  22. package/dist/{index-CWSchSql.d.ts → index-DQuTZ8xL.d.ts} +290 -13
  23. package/dist/index.d.ts +23 -29
  24. package/dist/index.js +776 -490
  25. package/dist/{errors → inference/errors}/index.d.ts +2 -2
  26. package/dist/{errors → inference/errors}/index.js +1 -1
  27. package/dist/inference/index.d.ts +10 -9
  28. package/dist/inference/index.js +34 -8
  29. package/dist/middleware/index.d.ts +5 -4
  30. package/dist/middleware/index.js +3 -3
  31. package/dist/models/index.d.ts +18 -16
  32. package/dist/models/index.js +47 -11
  33. package/dist/models/reasoning/index.d.ts +4 -0
  34. package/dist/{reasoning → models/reasoning}/index.js +2 -3
  35. package/dist/plugin/index.d.ts +414 -0
  36. package/dist/plugin/index.js +32 -0
  37. package/dist/presets/index.d.ts +3 -3
  38. package/dist/presets/index.js +7 -5
  39. package/dist/prompt/index.d.ts +6 -5
  40. package/dist/prompt/index.js +3 -2
  41. package/dist/runner-CI-XeR16.d.ts +91 -0
  42. package/dist/runtime/index.d.ts +7 -6
  43. package/dist/runtime/index.js +6 -7
  44. package/dist/safety/index.d.ts +1 -1
  45. package/dist/safety/index.js +1 -1
  46. package/dist/{session-manager-B_CWGTsl.d.ts → session-manager-KbYt2WUh.d.ts} +8 -0
  47. package/dist/signal/index.js +1 -1
  48. package/dist/skill/index.d.ts +2 -2
  49. package/dist/skill/index.js +3 -3
  50. package/dist/storage/index.d.ts +2 -2
  51. package/dist/storage/index.js +1 -1
  52. package/dist/sub-agent/index.d.ts +10 -9
  53. package/dist/sub-agent/index.js +21 -4
  54. package/dist/tool/index.d.ts +19 -5
  55. package/dist/tool/index.js +2 -2
  56. package/dist/{tool-BHbyUAy3.d.ts → tool-CZWN3KbO.d.ts} +1 -10
  57. package/dist/{tool-DLXAR9Ce.d.ts → tool-DkhSCV2Y.d.ts} +1 -1
  58. package/dist/tracking/index.d.ts +1 -1
  59. package/dist/tracking/index.js +1 -1
  60. package/dist/{types-KKDrdU9Y.d.ts → types-BlOKk-Bb.d.ts} +9 -4
  61. package/dist/{types-BnpEOYV-.d.ts → types-BlZwmnuW.d.ts} +1 -1
  62. package/dist/{runner-e2YRcUoX.d.ts → types-DTSkxakL.d.ts} +3 -138
  63. package/dist/{types-QKHHQLLq.d.ts → types-DmDwi2zI.d.ts} +7 -4
  64. package/package.json +15 -9
  65. package/dist/chunk-DWYX7ASF.js +0 -26
  66. package/dist/chunk-SQU2AJHO.js +0 -305
  67. package/dist/reasoning/index.d.ts +0 -116
  68. package/dist/types-QA4WhEfz.d.ts +0 -138
@@ -0,0 +1,102 @@
1
+ // src/presets/patterns.ts
2
+ function globToRegex(pattern) {
3
+ const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
4
+ return new RegExp(`^${escaped}$`, "i");
5
+ }
6
+ function matchesPatterns(id, patterns) {
7
+ return patterns.some((pattern) => globToRegex(pattern).test(id));
8
+ }
9
+ function filterTools(tools, options) {
10
+ const allowPatterns = options.allow ?? [];
11
+ const denyPatterns = options.deny ?? [];
12
+ return tools.filter((tool) => {
13
+ const matchesAllow = allowPatterns.length === 0 || matchesPatterns(tool.id, allowPatterns);
14
+ if (!matchesAllow) {
15
+ return false;
16
+ }
17
+ const matchesDeny = denyPatterns.length > 0 && matchesPatterns(tool.id, denyPatterns);
18
+ if (matchesDeny && allowPatterns.length === 0) {
19
+ return false;
20
+ }
21
+ return true;
22
+ });
23
+ }
24
+
25
+ // src/presets/apply.ts
26
+ function applyPreset(preset, availableTools, baseSystemPrompt) {
27
+ const tools = filterTools(availableTools, {
28
+ allow: preset.allowTools,
29
+ deny: preset.denyTools
30
+ });
31
+ let systemPrompt = preset.systemPrompt;
32
+ if (systemPrompt && baseSystemPrompt) {
33
+ systemPrompt = systemPrompt.replace("{basePrompt}", baseSystemPrompt);
34
+ }
35
+ return {
36
+ name: preset.name,
37
+ systemPrompt,
38
+ tools: tools.length > 0 ? tools : void 0,
39
+ temperature: preset.temperature,
40
+ maxSteps: preset.maxSteps,
41
+ reasoningLevel: preset.reasoningLevel,
42
+ model: preset.model
43
+ };
44
+ }
45
+ function mergePresets(...presets) {
46
+ if (presets.length === 0) {
47
+ throw new Error("mergePresets requires at least one preset");
48
+ }
49
+ if (presets.length === 1) {
50
+ return presets[0];
51
+ }
52
+ const [first, ...rest] = presets;
53
+ const allAllow = [];
54
+ const allDeny = [];
55
+ for (const preset of presets) {
56
+ if (preset.allowTools?.length) {
57
+ allAllow.push(preset.allowTools);
58
+ }
59
+ if (preset.denyTools?.length) {
60
+ allDeny.push(...preset.denyTools);
61
+ }
62
+ }
63
+ const combinedAllow = allAllow.length > 0 ? allAllow.reduce(
64
+ (left, right) => left.length <= right.length ? left : right
65
+ ) : void 0;
66
+ return {
67
+ name: presets.map((preset) => preset.name).join("+"),
68
+ description: presets.map((preset) => preset.description).join(" | "),
69
+ allowTools: combinedAllow,
70
+ denyTools: allDeny.length > 0 ? [...new Set(allDeny)] : void 0,
71
+ systemPrompt: rest.reduce(
72
+ (value, preset) => preset.systemPrompt ?? value,
73
+ first.systemPrompt
74
+ ),
75
+ temperature: rest.reduce(
76
+ (value, preset) => preset.temperature ?? value,
77
+ first.temperature
78
+ ),
79
+ maxSteps: rest.reduce(
80
+ (value, preset) => preset.maxSteps ?? value,
81
+ first.maxSteps
82
+ ),
83
+ reasoningLevel: rest.reduce(
84
+ (value, preset) => preset.reasoningLevel ?? value,
85
+ first.reasoningLevel
86
+ ),
87
+ model: rest.reduce((value, preset) => preset.model ?? value, first.model)
88
+ };
89
+ }
90
+ function createPreset(options) {
91
+ return {
92
+ description: options.description ?? `Custom preset: ${options.name}`,
93
+ ...options
94
+ };
95
+ }
96
+
97
+ export {
98
+ filterTools,
99
+ applyPreset,
100
+ mergePresets,
101
+ createPreset
102
+ };
@@ -3,16 +3,23 @@ import {
3
3
  } from "./chunk-WWYYNWEW.js";
4
4
  import {
5
5
  Inference
6
- } from "./chunk-N6HWIEEA.js";
6
+ } from "./chunk-WKHDSSXG.js";
7
7
  import {
8
8
  executeAgentToolCall
9
- } from "./chunk-7VKQ4WPB.js";
9
+ } from "./chunk-H3FUYU52.js";
10
+ import {
11
+ LLMError
12
+ } from "./chunk-4QFNWPIF.js";
10
13
  import {
11
14
  currentScope,
12
15
  snapshotScope,
13
16
  streamWithinScope,
14
17
  withinScope
15
18
  } from "./chunk-N7P4PN3O.js";
19
+ import {
20
+ extractModelId,
21
+ extractProvider
22
+ } from "./chunk-I6PKJ7XQ.js";
16
23
 
17
24
  // src/runtime/task/observer.ts
18
25
  function defaultAgentTaskCheckpointStrategy(input) {
@@ -763,6 +770,7 @@ async function handleContextOverflow(options) {
763
770
  // src/runtime/step-processing/process.ts
764
771
  async function processStepStream(stream, options) {
765
772
  const { abort, onEvent } = options;
773
+ const normalizeError = options.normalizeError ?? ((error2) => error2 instanceof Error ? error2 : new Error(String(error2)));
766
774
  const doomLoopThreshold = options.doomLoopThreshold ?? DEFAULT_DOOM_LOOP_THRESHOLD;
767
775
  const maxSteps = options.maxSteps ?? 50;
768
776
  let stepCount = options.currentStep ?? 1;
@@ -914,7 +922,7 @@ async function processStepStream(stream, options) {
914
922
  }
915
923
  }
916
924
  } catch (caught) {
917
- error = caught instanceof Error ? caught : new Error(String(caught));
925
+ error = normalizeError(caught);
918
926
  await onEvent({ type: "status", status: "error" });
919
927
  await onEvent({ type: "error", error });
920
928
  }
@@ -950,6 +958,13 @@ function buildModelCallContext(options) {
950
958
  scope: snapshotScope()
951
959
  };
952
960
  }
961
+ function normalizeModelStepError(options, error) {
962
+ const model = options.preparedStep.inferenceInput.model;
963
+ return LLMError.from(error, {
964
+ provider: extractProvider(model),
965
+ model: extractModelId(model)
966
+ });
967
+ }
953
968
  async function* runModelStep(options) {
954
969
  return yield* streamWithinScope(
955
970
  {
@@ -983,6 +998,7 @@ async function* runModelStep(options) {
983
998
  const processPromise = processStepStream(stream, {
984
999
  sessionID: preparedStep.inferenceInput.sessionID,
985
1000
  abort: preparedStep.inferenceInput.abort,
1001
+ normalizeError: (error) => normalizeModelStepError(options, error),
986
1002
  currentStep: preparedStep.step,
987
1003
  maxSteps: preparedStep.stepProcessing.maxSteps,
988
1004
  doomLoopThreshold: preparedStep.stepProcessing.doomLoopThreshold ?? 3,
@@ -1,6 +1,9 @@
1
+ import {
2
+ Presets
3
+ } from "./chunk-EKR6PKXU.js";
1
4
  import {
2
5
  Tool
3
- } from "./chunk-P6YF7USR.js";
6
+ } from "./chunk-MHKK374K.js";
4
7
 
5
8
  // src/sub-agent/types.ts
6
9
  var DEFAULT_MAX_CONCURRENT = 6;
@@ -169,7 +172,7 @@ var SubAgentTracker = class {
169
172
  }
170
173
  if (timeoutMs !== void 0 && timeoutMs > 0) {
171
174
  const timeout = new Promise(
172
- (resolve) => setTimeout(() => resolve({ timedOut: true }), timeoutMs)
175
+ (resolve2) => setTimeout(() => resolve2({ timedOut: true }), timeoutMs)
173
176
  );
174
177
  return Promise.race([...races, timeout]);
175
178
  }
@@ -550,10 +553,353 @@ function createSubAgentTools(parent, config) {
550
553
  return tools;
551
554
  }
552
555
 
556
+ // src/sub-agent/markdown-profile.ts
557
+ var FRONTMATTER_REGEX = /^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/;
558
+ var VALID_REASONING_LEVELS = /* @__PURE__ */ new Set([
559
+ "off",
560
+ "minimal",
561
+ "low",
562
+ "medium",
563
+ "high",
564
+ "xhigh"
565
+ ]);
566
+ function parseAgentFrontmatter(raw) {
567
+ const result = {};
568
+ const lines = raw.split("\n");
569
+ let i = 0;
570
+ while (i < lines.length) {
571
+ const line = lines[i];
572
+ if (line.trim() === "" || line.trim().startsWith("#")) {
573
+ i++;
574
+ continue;
575
+ }
576
+ const colonIndex = line.indexOf(":");
577
+ if (colonIndex === -1) {
578
+ i++;
579
+ continue;
580
+ }
581
+ const key = line.slice(0, colonIndex).trim();
582
+ let value = line.slice(colonIndex + 1).trim();
583
+ if (value === "|") {
584
+ const blockLines = [];
585
+ i++;
586
+ while (i < lines.length) {
587
+ const blockLine = lines[i];
588
+ if (blockLine.length > 0 && !blockLine.startsWith(" ") && !blockLine.startsWith(" ")) {
589
+ break;
590
+ }
591
+ blockLines.push(blockLine);
592
+ i++;
593
+ }
594
+ const minIndent = blockLines.filter((l) => l.trim().length > 0).reduce((min, l) => {
595
+ const indent = l.match(/^(\s*)/)?.[1].length ?? 0;
596
+ return Math.min(min, indent);
597
+ }, Infinity);
598
+ result[key] = blockLines.map((l) => l.trim().length === 0 ? "" : l.slice(minIndent)).join("\n").trim();
599
+ continue;
600
+ }
601
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
602
+ value = value.slice(1, -1);
603
+ }
604
+ if (key.length > 0) {
605
+ result[key] = value;
606
+ }
607
+ i++;
608
+ }
609
+ return result;
610
+ }
611
+ function parseMarkdownAgent(content, filePath) {
612
+ const match = content.match(FRONTMATTER_REGEX);
613
+ if (!match) {
614
+ return null;
615
+ }
616
+ const [, rawFrontmatter, body] = match;
617
+ const fields = parseAgentFrontmatter(rawFrontmatter);
618
+ if (!fields.name || !fields.description) {
619
+ return null;
620
+ }
621
+ const frontmatter = {
622
+ name: fields.name,
623
+ description: fields.description
624
+ };
625
+ if (fields.preset) frontmatter.preset = fields.preset;
626
+ if (fields.extends) frontmatter.extends = fields.extends;
627
+ if (fields.model) frontmatter.model = fields.model;
628
+ if (fields.maxSteps) frontmatter.maxSteps = fields.maxSteps;
629
+ if (fields.temperature) frontmatter.temperature = fields.temperature;
630
+ if (fields.reasoning) frontmatter.reasoning = fields.reasoning;
631
+ if (fields.tools) frontmatter.tools = fields.tools;
632
+ if (fields.skills) frontmatter.skills = fields.skills;
633
+ if (fields.canSpawn) frontmatter.canSpawn = fields.canSpawn;
634
+ return {
635
+ frontmatter,
636
+ body: body.trim(),
637
+ filePath
638
+ };
639
+ }
640
+ function parseToolSpec(raw) {
641
+ if (raw === void 0 || raw.trim() === "") {
642
+ return { mode: "inherit" };
643
+ }
644
+ const items = raw.split(",").map((s) => s.trim()).filter(Boolean);
645
+ if (items.length === 0) {
646
+ return { mode: "inherit" };
647
+ }
648
+ const hasModifiers = items.some((item) => item.startsWith("+") || item.startsWith("-"));
649
+ if (hasModifiers) {
650
+ const modifiers = items.map((item) => {
651
+ if (item.startsWith("+")) {
652
+ return { kind: "add", pattern: item.slice(1) };
653
+ }
654
+ if (item.startsWith("-")) {
655
+ return { kind: "remove", pattern: item.slice(1) };
656
+ }
657
+ return { kind: "add", pattern: item };
658
+ });
659
+ return { mode: "modifiers", modifiers };
660
+ }
661
+ return { mode: "explicit", patterns: items };
662
+ }
663
+ function toAgentProfile(parsed, resolvers = {}) {
664
+ const { frontmatter, body } = parsed;
665
+ const parent = frontmatter.extends ? resolvers.resolveParent?.(frontmatter.extends) : void 0;
666
+ const preset = frontmatter.preset ? resolvers.resolvePreset?.(frontmatter.preset) : parent?.preset;
667
+ let systemPrompt;
668
+ if (body.length > 0) {
669
+ const parentPrompt = parent?.systemPrompt ?? preset?.systemPrompt ?? "";
670
+ systemPrompt = body.includes("{basePrompt}") ? body.replace("{basePrompt}", parentPrompt) : body;
671
+ } else if (parent?.systemPrompt) {
672
+ systemPrompt = parent.systemPrompt;
673
+ }
674
+ const maxSteps = frontmatter.maxSteps ? parseInt(frontmatter.maxSteps, 10) : parent?.maxSteps;
675
+ let resolvedPreset = preset;
676
+ const temperature = frontmatter.temperature ? parseFloat(frontmatter.temperature) : void 0;
677
+ const reasoning = frontmatter.reasoning;
678
+ if (temperature !== void 0 || reasoning !== void 0) {
679
+ resolvedPreset = {
680
+ ...preset ?? { name: "custom", description: "Markdown-defined agent" },
681
+ ...temperature !== void 0 ? { temperature } : {},
682
+ ...reasoning !== void 0 && VALID_REASONING_LEVELS.has(reasoning) ? { reasoningLevel: reasoning } : {}
683
+ };
684
+ }
685
+ const toolSpec = parseToolSpec(frontmatter.tools);
686
+ if (toolSpec.mode === "explicit" || toolSpec.mode === "modifiers") {
687
+ resolvedPreset = {
688
+ ...resolvedPreset ?? { name: "custom", description: "Markdown-defined agent" }
689
+ };
690
+ if (toolSpec.mode === "explicit") {
691
+ resolvedPreset.allowTools = toolSpec.patterns;
692
+ resolvedPreset.denyTools = void 0;
693
+ } else {
694
+ const baseAllow = [...resolvedPreset.allowTools ?? []];
695
+ const baseDeny = [...resolvedPreset.denyTools ?? []];
696
+ for (const mod of toolSpec.modifiers) {
697
+ if (mod.kind === "add") {
698
+ baseAllow.push(mod.pattern);
699
+ const denyIdx = baseDeny.indexOf(mod.pattern);
700
+ if (denyIdx !== -1) baseDeny.splice(denyIdx, 1);
701
+ } else {
702
+ baseDeny.push(mod.pattern);
703
+ const allowIdx = baseAllow.indexOf(mod.pattern);
704
+ if (allowIdx !== -1) baseAllow.splice(allowIdx, 1);
705
+ }
706
+ }
707
+ if (baseAllow.length > 0) resolvedPreset.allowTools = baseAllow;
708
+ if (baseDeny.length > 0) resolvedPreset.denyTools = baseDeny;
709
+ }
710
+ }
711
+ const canSpawn = frontmatter.canSpawn ? frontmatter.canSpawn === "true" : parent?.canSpawn;
712
+ const profile = {
713
+ name: frontmatter.name,
714
+ description: frontmatter.description
715
+ };
716
+ if (resolvedPreset) profile.preset = resolvedPreset;
717
+ if (systemPrompt) profile.systemPrompt = systemPrompt;
718
+ if (maxSteps !== void 0 && !isNaN(maxSteps)) profile.maxSteps = maxSteps;
719
+ if (canSpawn !== void 0) profile.canSpawn = canSpawn;
720
+ if (frontmatter.model) {
721
+ profile._modelId = frontmatter.model;
722
+ }
723
+ if (frontmatter.skills) {
724
+ profile._skillNames = frontmatter.skills.split(",").map((s) => s.trim()).filter(Boolean);
725
+ }
726
+ profile._source = parsed.filePath;
727
+ return profile;
728
+ }
729
+ function isMarkdownProfile(profile) {
730
+ return "_source" in profile;
731
+ }
732
+
733
+ // src/sub-agent/discovery.ts
734
+ import { existsSync, readdirSync, readFileSync, statSync } from "fs";
735
+ import { homedir } from "os";
736
+ import { join, isAbsolute, resolve } from "path";
737
+ var DEFAULT_USER_DIR = join(homedir(), ".cuylabs", "agents");
738
+ var DEFAULT_PROJECT_DIR = ".cuylabs/agents";
739
+ var PRESET_MAP = {
740
+ explore: Presets.explore,
741
+ plan: Presets.plan,
742
+ review: Presets.review,
743
+ quick: Presets.quick,
744
+ careful: Presets.careful,
745
+ code: Presets.code,
746
+ watch: Presets.watch
747
+ };
748
+ function defaultResolvePreset(name) {
749
+ return PRESET_MAP[name.toLowerCase()];
750
+ }
751
+ function isLoadableMarkdown(filename) {
752
+ return filename.endsWith(".md") && !filename.startsWith("_") && !filename.startsWith(".");
753
+ }
754
+ function loadAgentDir(dir, source, resolvers, errors) {
755
+ if (!existsSync(dir)) return [];
756
+ let stat;
757
+ try {
758
+ stat = statSync(dir);
759
+ } catch {
760
+ return [];
761
+ }
762
+ if (!stat.isDirectory()) return [];
763
+ const results = [];
764
+ let entries;
765
+ try {
766
+ entries = readdirSync(dir, { withFileTypes: true });
767
+ } catch {
768
+ return [];
769
+ }
770
+ for (const entry of entries) {
771
+ if (!entry.isFile() && !entry.isSymbolicLink()) continue;
772
+ if (!isLoadableMarkdown(entry.name)) continue;
773
+ const filePath = join(dir, entry.name);
774
+ try {
775
+ const content = readFileSync(filePath, "utf-8");
776
+ const parsed = parseMarkdownAgent(content, filePath);
777
+ if (!parsed) {
778
+ errors.push({ path: filePath, error: "Missing required frontmatter (name, description)" });
779
+ continue;
780
+ }
781
+ const profile = toAgentProfile(parsed, resolvers);
782
+ results.push({ profile, source, filePath });
783
+ } catch (err) {
784
+ errors.push({
785
+ path: filePath,
786
+ error: err instanceof Error ? err.message : String(err)
787
+ });
788
+ }
789
+ }
790
+ return results;
791
+ }
792
+ function loadAgentFile(filePath, source, resolvers, errors) {
793
+ if (!existsSync(filePath)) {
794
+ errors.push({ path: filePath, error: "File not found" });
795
+ return null;
796
+ }
797
+ try {
798
+ const content = readFileSync(filePath, "utf-8");
799
+ const parsed = parseMarkdownAgent(content, filePath);
800
+ if (!parsed) {
801
+ errors.push({ path: filePath, error: "Missing required frontmatter (name, description)" });
802
+ return null;
803
+ }
804
+ const profile = toAgentProfile(parsed, resolvers);
805
+ return { profile, source, filePath };
806
+ } catch (err) {
807
+ errors.push({
808
+ path: filePath,
809
+ error: err instanceof Error ? err.message : String(err)
810
+ });
811
+ return null;
812
+ }
813
+ }
814
+ function discoverAgentProfiles(options) {
815
+ const {
816
+ cwd,
817
+ userDir = DEFAULT_USER_DIR,
818
+ projectDir = DEFAULT_PROJECT_DIR,
819
+ configPaths = [],
820
+ builtInProfiles = [],
821
+ resolvePreset: customResolvePreset
822
+ } = options;
823
+ const errors = [];
824
+ const discovered = [];
825
+ const presetResolver = customResolvePreset ?? defaultResolvePreset;
826
+ const firstPassResolvers = {
827
+ resolvePreset: presetResolver
828
+ // resolveParent deferred to merge phase
829
+ };
830
+ for (const profile of builtInProfiles) {
831
+ discovered.push({ profile, source: "builtin" });
832
+ }
833
+ const userProfiles = loadAgentDir(userDir, "user", firstPassResolvers, errors);
834
+ discovered.push(...userProfiles);
835
+ const projectAgentsDir = resolve(cwd, projectDir);
836
+ const projectProfiles = loadAgentDir(projectAgentsDir, "project", firstPassResolvers, errors);
837
+ discovered.push(...projectProfiles);
838
+ for (const configPath of configPaths) {
839
+ const resolved = isAbsolute(configPath) ? configPath : resolve(cwd, configPath);
840
+ const entry = loadAgentFile(resolved, "config", firstPassResolvers, errors);
841
+ if (entry) discovered.push(entry);
842
+ }
843
+ const profileMap = /* @__PURE__ */ new Map();
844
+ for (const entry of discovered) {
845
+ profileMap.set(entry.profile.name, entry);
846
+ }
847
+ const merged = /* @__PURE__ */ new Map();
848
+ for (const [name, entry] of profileMap) {
849
+ const profile = entry.profile;
850
+ const md = profile;
851
+ if ("_source" in md) {
852
+ }
853
+ merged.set(name, profile);
854
+ }
855
+ const allProfiles = merged;
856
+ for (const [name, entry] of profileMap) {
857
+ const profile = entry.profile;
858
+ if (!("_source" in profile)) continue;
859
+ const md = profile;
860
+ if (!md._source) continue;
861
+ try {
862
+ const content = readFileSync(md._source, "utf-8");
863
+ const parsed = parseMarkdownAgent(content, md._source);
864
+ if (parsed?.frontmatter.extends) {
865
+ const parentName = parsed.frontmatter.extends;
866
+ const parent = allProfiles.get(parentName);
867
+ if (parent) {
868
+ const resolvedProfile = toAgentProfile(parsed, {
869
+ resolvePreset: presetResolver,
870
+ resolveParent: (n) => allProfiles.get(n)
871
+ });
872
+ merged.set(name, resolvedProfile);
873
+ }
874
+ }
875
+ } catch {
876
+ }
877
+ }
878
+ return {
879
+ profiles: Array.from(merged.values()),
880
+ discovered: Array.from(profileMap.values()),
881
+ errors
882
+ };
883
+ }
884
+ function getUserAgentsDir() {
885
+ return DEFAULT_USER_DIR;
886
+ }
887
+ function getProjectAgentsDir(cwd) {
888
+ return resolve(cwd, DEFAULT_PROJECT_DIR);
889
+ }
890
+
553
891
  export {
554
892
  DEFAULT_MAX_CONCURRENT,
555
893
  DEFAULT_MAX_SPAWN_DEPTH,
556
894
  DEFAULT_SESSION_TITLE_PREFIX,
557
895
  SubAgentTracker,
558
- createSubAgentTools
896
+ createSubAgentTools,
897
+ parseAgentFrontmatter,
898
+ parseMarkdownAgent,
899
+ parseToolSpec,
900
+ toAgentProfile,
901
+ isMarkdownProfile,
902
+ discoverAgentProfiles,
903
+ getUserAgentsDir,
904
+ getProjectAgentsDir
559
905
  };
@@ -1,15 +1,21 @@
1
1
  import {
2
2
  createApprovalHandler
3
- } from "./chunk-BFM2YHNM.js";
3
+ } from "./chunk-5ARZJWD2.js";
4
4
  import {
5
- getModelId,
6
- getProviderId
7
- } from "./chunk-DWYX7ASF.js";
5
+ extractModelId,
6
+ extractProvider
7
+ } from "./chunk-I6PKJ7XQ.js";
8
8
 
9
9
  // src/middleware/runner.ts
10
10
  function isBlockedModelCall(value) {
11
11
  return "block" in value && value.block === true;
12
12
  }
13
+ function logMiddlewareWarning(middlewareName, hook, error) {
14
+ console.warn(
15
+ `[middleware] "${middlewareName}" ${hook} error:`,
16
+ error instanceof Error ? error.message : String(error)
17
+ );
18
+ }
13
19
  var MiddlewareRunner = class {
14
20
  stack;
15
21
  constructor(middleware = []) {
@@ -67,10 +73,7 @@ var MiddlewareRunner = class {
67
73
  current = next;
68
74
  }
69
75
  } catch (err) {
70
- console.warn(
71
- `[middleware] "${mw.name}" model.chunk error:`,
72
- err instanceof Error ? err.message : String(err)
73
- );
76
+ logMiddlewareWarning(mw.name, "model.chunk", err);
74
77
  }
75
78
  }
76
79
  return current ?? void 0;
@@ -89,10 +92,7 @@ var MiddlewareRunner = class {
89
92
  current = next;
90
93
  }
91
94
  } catch (err) {
92
- console.warn(
93
- `[middleware] "${mw.name}" model.output error:`,
94
- err instanceof Error ? err.message : String(err)
95
- );
95
+ logMiddlewareWarning(mw.name, "model.output", err);
96
96
  }
97
97
  }
98
98
  return current;
@@ -142,10 +142,7 @@ var MiddlewareRunner = class {
142
142
  try {
143
143
  current = await mw.afterToolCall(tool, args, current, ctx);
144
144
  } catch (err) {
145
- console.warn(
146
- `[middleware] "${mw.name}" afterToolCall error:`,
147
- err instanceof Error ? err.message : String(err)
148
- );
145
+ logMiddlewareWarning(mw.name, "afterToolCall", err);
149
146
  }
150
147
  }
151
148
  return current;
@@ -172,10 +169,7 @@ var MiddlewareRunner = class {
172
169
  sections.push(result);
173
170
  }
174
171
  } catch (err) {
175
- console.warn(
176
- `[middleware] "${mw.name}" promptSections error:`,
177
- err instanceof Error ? err.message : String(err)
178
- );
172
+ logMiddlewareWarning(mw.name, "promptSections", err);
179
173
  }
180
174
  }
181
175
  return sections;
@@ -226,10 +220,7 @@ var MiddlewareRunner = class {
226
220
  try {
227
221
  await mw.onChatStart(sessionId, message);
228
222
  } catch (err) {
229
- console.warn(
230
- `[middleware] "${mw.name}" onChatStart error:`,
231
- err instanceof Error ? err.message : String(err)
232
- );
223
+ logMiddlewareWarning(mw.name, "onChatStart", err);
233
224
  }
234
225
  }
235
226
  }
@@ -248,10 +239,7 @@ var MiddlewareRunner = class {
248
239
  try {
249
240
  await mw.onChatEnd(sessionId, result);
250
241
  } catch (err) {
251
- console.warn(
252
- `[middleware] "${mw.name}" onChatEnd error:`,
253
- err instanceof Error ? err.message : String(err)
254
- );
242
+ logMiddlewareWarning(mw.name, "onChatEnd", err);
255
243
  }
256
244
  }
257
245
  }
@@ -547,14 +535,14 @@ async function createAndRegisterProvider(spanProcessor, serviceName) {
547
535
 
548
536
  // src/middleware/prompt-cache/cache.ts
549
537
  function detectCacheProvider(input) {
550
- const provider = getProviderId(input.model);
538
+ const provider = extractProvider(input.model);
551
539
  if (provider) {
552
540
  const p = provider.toLowerCase();
553
541
  if (p === "anthropic") return "anthropic";
554
542
  if (p === "openai") return "openai";
555
543
  if (p === "google") return "google";
556
544
  }
557
- const modelId = getModelId(input.model);
545
+ const modelId = extractModelId(input.model);
558
546
  if (/claude/i.test(modelId)) return "anthropic";
559
547
  return "unknown";
560
548
  }