@polka-codes/core 0.9.0 → 0.9.2

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/index.js CHANGED
@@ -4,176 +4,6 @@ var __export = (target, all) => {
4
4
  __defProp(target, name, { get: all[name], enumerable: true });
5
5
  };
6
6
 
7
- // src/UsageMeter.ts
8
- var UsageMeter = class {
9
- #totals = { input: 0, output: 0, cachedRead: 0, cost: 0 };
10
- #calls = 0;
11
- #modelInfos;
12
- #maxMessages;
13
- #maxCost;
14
- constructor(modelInfos = {}, opts = {}) {
15
- const infos = {};
16
- for (const [provider, providerInfo] of Object.entries(modelInfos)) {
17
- for (const [model, modelInfo] of Object.entries(providerInfo)) {
18
- infos[`${provider.split("-")[0]}:${model.replace(/[\.-]/g, "")}`] = {
19
- inputPrice: modelInfo.inputPrice ?? 0,
20
- outputPrice: modelInfo.outputPrice ?? 0,
21
- cacheWritesPrice: modelInfo.cacheWritesPrice ?? 0,
22
- cacheReadsPrice: modelInfo.cacheReadsPrice ?? 0
23
- };
24
- }
25
- }
26
- this.#modelInfos = infos;
27
- this.#maxMessages = opts.maxMessages ?? 1e3;
28
- this.#maxCost = opts.maxCost ?? 100;
29
- }
30
- #calculageUsage(usage, providerMetadata, modelInfo) {
31
- const providerMetadataKey = Object.keys(providerMetadata ?? {})[0];
32
- const metadata = providerMetadata?.[providerMetadataKey] ?? {};
33
- switch (providerMetadataKey) {
34
- case "openrouter":
35
- return {
36
- input: usage.inputTokens ?? 0,
37
- output: usage.outputTokens ?? 0,
38
- cachedRead: usage.cachedInputTokens ?? 0,
39
- cost: metadata.usage?.cost ?? 0
40
- };
41
- case "anthropic": {
42
- const cachedRead = usage.cachedInputTokens ?? 0;
43
- const cacheWrite = metadata?.promptCacheMissTokens ?? 0;
44
- const input = usage.inputTokens ?? 0;
45
- const output = usage.outputTokens ?? 0;
46
- return {
47
- input: input + cacheWrite + cachedRead,
48
- output,
49
- cachedRead,
50
- cost: (input * modelInfo.inputPrice + output * modelInfo.outputPrice + cacheWrite * modelInfo.cacheWritesPrice + cachedRead * modelInfo.cacheReadsPrice) / 1e6
51
- };
52
- }
53
- case "deepseek": {
54
- const cachedRead = usage.cachedInputTokens ?? 0;
55
- const cacheWrite = metadata.promptCacheMissTokens ?? 0;
56
- const input = usage.inputTokens ?? 0;
57
- const output = usage.outputTokens ?? 0;
58
- return {
59
- input,
60
- output,
61
- cachedRead,
62
- cost: (output * modelInfo.outputPrice + cacheWrite * modelInfo.inputPrice + cachedRead * modelInfo.cacheReadsPrice) / 1e6
63
- };
64
- }
65
- default: {
66
- const cachedRead = usage.cachedInputTokens ?? 0;
67
- const input = usage.inputTokens ?? 0;
68
- const output = usage.outputTokens ?? 0;
69
- return {
70
- input,
71
- output,
72
- cachedRead,
73
- cost: (input * modelInfo.inputPrice + output * modelInfo.outputPrice) / 1e6
74
- };
75
- }
76
- }
77
- }
78
- addUsage(llm, resp, options = {}) {
79
- const modelInfo = options.modelInfo ?? // make google.vertex.chat to google
80
- // and anthropic.messages to anthropic
81
- this.#modelInfos[`${llm.provider.split(".")[0]}:${llm.modelId.replace(/[\.-]/g, "")}`] ?? {
82
- inputPrice: 0,
83
- outputPrice: 0,
84
- cacheWritesPrice: 0,
85
- cacheReadsPrice: 0
86
- };
87
- const usage = "totalUsage" in resp ? resp.totalUsage : resp.usage;
88
- const result = this.#calculageUsage(usage, resp.providerMetadata, modelInfo);
89
- this.#totals.input += result.input;
90
- this.#totals.output += result.output;
91
- this.#totals.cachedRead += result.cachedRead;
92
- this.#totals.cost += result.cost;
93
- this.#calls++;
94
- }
95
- /** Override the running totals (e.g., restore from saved state). */
96
- setUsage(newUsage) {
97
- if (newUsage.input != null) this.#totals.input = newUsage.input;
98
- if (newUsage.output != null) this.#totals.output = newUsage.output;
99
- if (newUsage.cachedRead != null) this.#totals.cachedRead = newUsage.cachedRead;
100
- if (newUsage.cost != null) this.#totals.cost = newUsage.cost;
101
- if (newUsage.calls != null) this.#calls = newUsage.calls;
102
- }
103
- /** Manually bump the message count (useful if you record some calls without token info). */
104
- incrementMessageCount(n = 1) {
105
- this.#calls += n;
106
- }
107
- /** Return true once either messages or cost exceed the configured caps. */
108
- isLimitExceeded() {
109
- const messageCount = this.#maxMessages !== void 0 && this.#calls >= this.#maxMessages;
110
- const cost = this.#maxCost !== void 0 && this.#totals.cost >= this.#maxCost;
111
- return {
112
- messageCount,
113
- maxMessages: this.#maxMessages,
114
- cost,
115
- maxCost: this.#maxCost,
116
- result: messageCount || cost
117
- };
118
- }
119
- /** Same as isLimitExceeded but throws an error if a limit is hit. */
120
- checkLimit() {
121
- const result = this.isLimitExceeded();
122
- if (result.result) {
123
- throw new Error(
124
- `Usage limit exceeded. Message count: ${result.messageCount}/${result.maxMessages}, cost: ${result.cost}/${result.maxCost}`
125
- );
126
- }
127
- }
128
- /** Getter for the aggregated totals (immutable copy). */
129
- get usage() {
130
- return { ...this.#totals, messageCount: this.#calls };
131
- }
132
- /** Print a concise usage summary to console. */
133
- printUsage() {
134
- const u = this.usage;
135
- console.log(
136
- `Usage - messages: ${u.messageCount}, input: ${u.input}, cached: ${u.cachedRead}, output: ${u.output}, cost: $${u.cost.toFixed(4)}`
137
- );
138
- }
139
- onFinishHandler(llm) {
140
- return (evt) => {
141
- this.addUsage(llm, evt);
142
- };
143
- }
144
- };
145
-
146
- // src/tools/provider.ts
147
- var MockProvider = class {
148
- async readFile(path) {
149
- return "mock content";
150
- }
151
- async writeFile(path, content) {
152
- return;
153
- }
154
- async removeFile(path) {
155
- return;
156
- }
157
- async renameFile(sourcePath, targetPath) {
158
- return;
159
- }
160
- async listFiles(path, recursive, maxCount) {
161
- return [["mock-file.txt"], false];
162
- }
163
- async searchFiles(path, regex, filePattern) {
164
- return ["mock-file.txt"];
165
- }
166
- async executeCommand(command, needApprove) {
167
- return { stdout: "mock output", stderr: "", exitCode: 0 };
168
- }
169
- async askFollowupQuestion(question, options) {
170
- return "mock answer";
171
- }
172
- async attemptCompletion(result) {
173
- return "mock completion";
174
- }
175
- };
176
-
177
7
  // src/tools/allTools.ts
178
8
  var allTools_exports = {};
179
9
  __export(allTools_exports, {
@@ -358,7 +188,7 @@ var handler2 = async (provider, args) => {
358
188
  message: `<user_message>${moreMessage}</user_message>`
359
189
  };
360
190
  };
361
- var isAvailable2 = (provider) => {
191
+ var isAvailable2 = (_provider) => {
362
192
  return true;
363
193
  };
364
194
  var attemptCompletion_default = {
@@ -589,22 +419,88 @@ var fetchUrl_default = {
589
419
  isAvailable: isAvailable5
590
420
  };
591
421
 
592
- // src/tools/listFiles.ts
422
+ // src/tools/handOver.ts
593
423
  import { z as z6 } from "zod";
594
424
  var toolInfo6 = {
425
+ name: "hand_over",
426
+ description: "Hand over the current task to another agent to complete. This tool MUST NOT to be used with any other tool.",
427
+ parameters: z6.object({
428
+ agentName: z6.string().describe("The name of the agent to hand over the task to").meta({ usageValue: "Name of the target agent" }),
429
+ task: z6.string().describe("The task to be completed by the target agent").meta({ usageValue: "Task description" }),
430
+ context: z6.string().describe("The context information for the task").meta({ usageValue: "Context information" }),
431
+ files: z6.preprocess((val) => {
432
+ if (!val) return [];
433
+ const values = Array.isArray(val) ? val : [val];
434
+ return values.flatMap((i) => typeof i === "string" ? i.split(",") : []).filter((s) => s.length > 0);
435
+ }, z6.array(z6.string())).optional().describe("The files relevant to the task. Comma separated paths").meta({ usageValue: "Relevant files" })
436
+ }),
437
+ examples: [
438
+ {
439
+ description: "Hand over a coding task to the coder agent",
440
+ parameters: [
441
+ {
442
+ name: "agentName",
443
+ value: "coder"
444
+ },
445
+ {
446
+ name: "task",
447
+ value: "Implement the login feature"
448
+ },
449
+ {
450
+ name: "context",
451
+ value: "We need a secure login system with email and password"
452
+ },
453
+ {
454
+ name: "files",
455
+ value: "src/auth/login.ts,src/auth/types.ts"
456
+ }
457
+ ]
458
+ }
459
+ ],
460
+ permissionLevel: 0 /* None */
461
+ };
462
+ var handler6 = async (_provider, args) => {
463
+ const parsed = toolInfo6.parameters.safeParse(args);
464
+ if (!parsed.success) {
465
+ return {
466
+ type: "Invalid" /* Invalid */,
467
+ message: `Invalid arguments for hand_over: ${parsed.error.message}`
468
+ };
469
+ }
470
+ const { agentName, task, context, files } = parsed.data;
471
+ return {
472
+ type: "HandOver" /* HandOver */,
473
+ agentName,
474
+ task,
475
+ context,
476
+ files: files ?? []
477
+ };
478
+ };
479
+ var isAvailable6 = (_provider) => {
480
+ return true;
481
+ };
482
+ var handOver_default = {
483
+ ...toolInfo6,
484
+ handler: handler6,
485
+ isAvailable: isAvailable6
486
+ };
487
+
488
+ // src/tools/listFiles.ts
489
+ import { z as z7 } from "zod";
490
+ var toolInfo7 = {
595
491
  name: "list_files",
596
492
  description: "Request to list files and directories within the specified directory. If recursive is true, it will list all files and directories recursively. If recursive is false or not provided, it will only list the top-level contents. Do not use this tool to confirm the existence of files you may have created, as the user will let you know if the files were created successfully or not.",
597
- parameters: z6.object({
598
- path: z6.string().describe("The path of the directory to list contents for (relative to the current working directory)").meta({ usageValue: "Directory path here" }),
599
- maxCount: z6.coerce.number().optional().default(2e3).describe("The maximum number of files to list. Default to 2000").meta({ usageValue: "Maximum number of files to list (optional)" }),
600
- recursive: z6.preprocess((val) => {
493
+ parameters: z7.object({
494
+ path: z7.string().describe("The path of the directory to list contents for (relative to the current working directory)").meta({ usageValue: "Directory path here" }),
495
+ maxCount: z7.coerce.number().optional().default(2e3).describe("The maximum number of files to list. Default to 2000").meta({ usageValue: "Maximum number of files to list (optional)" }),
496
+ recursive: z7.preprocess((val) => {
601
497
  if (typeof val === "string") {
602
498
  const lower = val.toLowerCase();
603
499
  if (lower === "false") return false;
604
500
  if (lower === "true") return true;
605
501
  }
606
502
  return val;
607
- }, z6.boolean().optional().default(true)).describe("Whether to list files recursively. Use true for recursive listing, false or omit for top-level only.").meta({ usageValue: "true or false (optional)" })
503
+ }, z7.boolean().optional().default(true)).describe("Whether to list files recursively. Use true for recursive listing, false or omit for top-level only.").meta({ usageValue: "true or false (optional)" })
608
504
  }),
609
505
  examples: [
610
506
  {
@@ -623,14 +519,14 @@ var toolInfo6 = {
623
519
  ],
624
520
  permissionLevel: 1 /* Read */
625
521
  };
626
- var handler6 = async (provider, args) => {
522
+ var handler7 = async (provider, args) => {
627
523
  if (!provider.listFiles) {
628
524
  return {
629
525
  type: "Error" /* Error */,
630
526
  message: "Not possible to list files. Abort."
631
527
  };
632
528
  }
633
- const { path, maxCount, recursive } = toolInfo6.parameters.parse(args);
529
+ const { path, maxCount, recursive } = toolInfo7.parameters.parse(args);
634
530
  const [files, limitReached] = await provider.listFiles(path, recursive, maxCount);
635
531
  return {
636
532
  type: "Reply" /* Reply */,
@@ -641,26 +537,26 @@ ${files.join("\n")}
641
537
  <list_files_truncated>${limitReached}</list_files_truncated>`
642
538
  };
643
539
  };
644
- var isAvailable6 = (provider) => {
540
+ var isAvailable7 = (provider) => {
645
541
  return !!provider.listFiles;
646
542
  };
647
543
  var listFiles_default = {
648
- ...toolInfo6,
649
- handler: handler6,
650
- isAvailable: isAvailable6
544
+ ...toolInfo7,
545
+ handler: handler7,
546
+ isAvailable: isAvailable7
651
547
  };
652
548
 
653
549
  // src/tools/readFile.ts
654
- import { z as z7 } from "zod";
655
- var toolInfo7 = {
550
+ import { z as z8 } from "zod";
551
+ var toolInfo8 = {
656
552
  name: "read_file",
657
553
  description: "Request to read the contents of one or multiple files at the specified paths. Use comma separated paths to read multiple files. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. May not be suitable for other types of binary files, as it returns the raw content as a string. Try to list all the potential files are relevent to the task, and then use this tool to read all the relevant files.",
658
- parameters: z7.object({
659
- path: z7.preprocess((val) => {
554
+ parameters: z8.object({
555
+ path: z8.preprocess((val) => {
660
556
  if (!val) return [];
661
557
  const values = Array.isArray(val) ? val : [val];
662
558
  return values.flatMap((i) => typeof i === "string" ? i.split(",") : []).filter((s) => s.length > 0);
663
- }, z7.array(z7.string())).describe("The path of the file to read").meta({ usageValue: "Comma separated paths here" })
559
+ }, z8.array(z8.string())).describe("The path of the file to read").meta({ usageValue: "Comma separated paths here" })
664
560
  }),
665
561
  examples: [
666
562
  {
@@ -684,14 +580,14 @@ var toolInfo7 = {
684
580
  ],
685
581
  permissionLevel: 1 /* Read */
686
582
  };
687
- var handler7 = async (provider, args) => {
583
+ var handler8 = async (provider, args) => {
688
584
  if (!provider.readFile) {
689
585
  return {
690
586
  type: "Error" /* Error */,
691
587
  message: "Not possible to read file. Abort."
692
588
  };
693
589
  }
694
- const { path: paths } = toolInfo7.parameters.parse(args);
590
+ const { path: paths } = toolInfo8.parameters.parse(args);
695
591
  const resp = [];
696
592
  for (const path of paths) {
697
593
  const fileContent = await provider.readFile(path);
@@ -711,26 +607,126 @@ var handler7 = async (provider, args) => {
711
607
  message: resp.join("\n")
712
608
  };
713
609
  };
714
- var isAvailable7 = (provider) => {
610
+ var isAvailable8 = (provider) => {
715
611
  return !!provider.readFile;
716
612
  };
717
613
  var readFile_default = {
718
- ...toolInfo7,
719
- handler: handler7,
720
- isAvailable: isAvailable7
614
+ ...toolInfo8,
615
+ handler: handler8,
616
+ isAvailable: isAvailable8
721
617
  };
722
618
 
723
- // src/tools/replaceInFile.ts
724
- import { z as z8 } from "zod";
725
-
726
- // src/tools/utils/replaceInFile.ts
727
- var replaceInFile = (fileContent, diff) => {
728
- const blockPattern = /<<<<<+ SEARCH>?\s*\r?\n([\s\S]*?)\r?\n=======[ \t]*\r?\n([\s\S]*?)\r?\n?>>>>>+ REPLACE/g;
729
- const blocks = [];
730
- for (let match = blockPattern.exec(diff); match !== null; match = blockPattern.exec(diff)) {
731
- blocks.push({ search: match[1], replace: match[2] });
732
- }
733
- if (blocks.length === 0) {
619
+ // src/tools/removeFile.ts
620
+ import { z as z9 } from "zod";
621
+ var toolInfo9 = {
622
+ name: "remove_file",
623
+ description: "Request to remove a file at the specified path.",
624
+ parameters: z9.object({
625
+ path: z9.string().describe("The path of the file to remove").meta({ usageValue: "File path here" })
626
+ }),
627
+ examples: [
628
+ {
629
+ description: "Request to remove a file",
630
+ parameters: [
631
+ {
632
+ name: "path",
633
+ value: "src/main.js"
634
+ }
635
+ ]
636
+ }
637
+ ],
638
+ permissionLevel: 2 /* Write */
639
+ };
640
+ var handler9 = async (provider, args) => {
641
+ if (!provider.removeFile) {
642
+ return {
643
+ type: "Error" /* Error */,
644
+ message: "Not possible to remove file. Abort."
645
+ };
646
+ }
647
+ const parsed = toolInfo9.parameters.safeParse(args);
648
+ if (!parsed.success) {
649
+ return {
650
+ type: "Invalid" /* Invalid */,
651
+ message: `Invalid arguments for remove_file: ${parsed.error.message}`
652
+ };
653
+ }
654
+ const { path } = parsed.data;
655
+ await provider.removeFile(path);
656
+ return {
657
+ type: "Reply" /* Reply */,
658
+ message: `<remove_file_path>${path}</remove_file_path><status>Success</status>`
659
+ };
660
+ };
661
+ var isAvailable9 = (provider) => {
662
+ return !!provider.removeFile;
663
+ };
664
+ var removeFile_default = {
665
+ ...toolInfo9,
666
+ handler: handler9,
667
+ isAvailable: isAvailable9
668
+ };
669
+
670
+ // src/tools/renameFile.ts
671
+ import { z as z10 } from "zod";
672
+ var toolInfo10 = {
673
+ name: "rename_file",
674
+ description: "Request to rename a file from source path to target path.",
675
+ parameters: z10.object({
676
+ source_path: z10.string().describe("The current path of the file").meta({ usageValue: "Source file path here" }),
677
+ target_path: z10.string().describe("The new path for the file").meta({ usageValue: "Target file path here" })
678
+ }),
679
+ examples: [
680
+ {
681
+ description: "Request to rename a file",
682
+ parameters: [
683
+ {
684
+ name: "source_path",
685
+ value: "src/old-name.js"
686
+ },
687
+ {
688
+ name: "target_path",
689
+ value: "src/new-name.js"
690
+ }
691
+ ]
692
+ }
693
+ ],
694
+ permissionLevel: 2 /* Write */
695
+ };
696
+ var handler10 = async (provider, args) => {
697
+ if (!provider.renameFile) {
698
+ return {
699
+ type: "Error" /* Error */,
700
+ message: "Not possible to rename file. Abort."
701
+ };
702
+ }
703
+ const { source_path, target_path } = toolInfo10.parameters.parse(args);
704
+ await provider.renameFile(source_path, target_path);
705
+ return {
706
+ type: "Reply" /* Reply */,
707
+ message: `<rename_file_path>${target_path}</rename_file_path><status>Success</status>`
708
+ };
709
+ };
710
+ var isAvailable10 = (provider) => {
711
+ return !!provider.renameFile;
712
+ };
713
+ var renameFile_default = {
714
+ ...toolInfo10,
715
+ handler: handler10,
716
+ isAvailable: isAvailable10
717
+ };
718
+
719
+ // src/tools/replaceInFile.ts
720
+ import { z as z11 } from "zod";
721
+
722
+ // src/tools/utils/replaceInFile.ts
723
+ var replaceInFile = (fileContent, diff) => {
724
+ const blockPattern = /<<<<<+ SEARCH>?\s*\r?\n([\s\S]*?)\r?\n=======[ \t]*\r?\n([\s\S]*?)\r?\n?>>>>>+ REPLACE/g;
725
+ const blocks = [];
726
+ for (let match = blockPattern.exec(diff); match !== null; match = blockPattern.exec(diff)) {
727
+ blocks.push({ search: match[1], replace: match[2] });
728
+ }
729
+ if (blocks.length === 0) {
734
730
  throw new Error("No valid diff blocks found.");
735
731
  }
736
732
  const findAndReplace = (content, search, replace) => {
@@ -798,12 +794,12 @@ var replaceInFile = (fileContent, diff) => {
798
794
  };
799
795
 
800
796
  // src/tools/replaceInFile.ts
801
- var toolInfo8 = {
797
+ var toolInfo11 = {
802
798
  name: "replace_in_file",
803
799
  description: "Request to replace sections of content in an existing file using SEARCH/REPLACE blocks that define exact changes to specific parts of the file. This tool should be used when you need to make targeted changes to specific parts of a file.",
804
- parameters: z8.object({
805
- path: z8.string().describe("The path of the file to modify").meta({ usageValue: "File path here" }),
806
- diff: z8.string().describe(
800
+ parameters: z11.object({
801
+ path: z11.string().describe("The path of the file to modify").meta({ usageValue: "File path here" }),
802
+ diff: z11.string().describe(
807
803
  `One or more SEARCH/REPLACE blocks following this exact format:
808
804
  \`\`\`
809
805
  <<<<<<< SEARCH
@@ -934,7 +930,7 @@ function oldFeature() {
934
930
  ],
935
931
  permissionLevel: 2 /* Write */
936
932
  };
937
- var handler8 = async (provider, args) => {
933
+ var handler11 = async (provider, args) => {
938
934
  if (!provider.readFile || !provider.writeFile) {
939
935
  return {
940
936
  type: "Error" /* Error */,
@@ -942,7 +938,7 @@ var handler8 = async (provider, args) => {
942
938
  };
943
939
  }
944
940
  try {
945
- const { path, diff } = toolInfo8.parameters.parse(args);
941
+ const { path, diff } = toolInfo11.parameters.parse(args);
946
942
  const fileContent = await provider.readFile(path);
947
943
  if (fileContent == null) {
948
944
  return {
@@ -979,28 +975,28 @@ var handler8 = async (provider, args) => {
979
975
  };
980
976
  }
981
977
  };
982
- var isAvailable8 = (provider) => {
978
+ var isAvailable11 = (provider) => {
983
979
  return !!provider.readFile && !!provider.writeFile;
984
980
  };
985
981
  var replaceInFile_default = {
986
- ...toolInfo8,
987
- handler: handler8,
988
- isAvailable: isAvailable8
982
+ ...toolInfo11,
983
+ handler: handler11,
984
+ isAvailable: isAvailable11
989
985
  };
990
986
 
991
987
  // src/tools/searchFiles.ts
992
- import { z as z9 } from "zod";
993
- var toolInfo9 = {
988
+ import { z as z12 } from "zod";
989
+ var toolInfo12 = {
994
990
  name: "search_files",
995
991
  description: "Request to perform a regex search across files in a specified directory, outputting context-rich results that include surrounding lines. This tool searches for patterns or specific content across multiple files, displaying each match with encapsulating context.",
996
- parameters: z9.object({
997
- path: z9.string().describe(
992
+ parameters: z12.object({
993
+ path: z12.string().describe(
998
994
  "The path of the directory to search in (relative to the current working directory). This directory will be recursively searched."
999
995
  ).meta({ usageValue: "Directory path here" }),
1000
- regex: z9.string().describe("The regular expression pattern to search for. Uses Rust regex syntax.").meta({
996
+ regex: z12.string().describe("The regular expression pattern to search for. Uses Rust regex syntax.").meta({
1001
997
  usageValue: "Your regex pattern here"
1002
998
  }),
1003
- filePattern: z9.string().optional().describe(
999
+ filePattern: z12.string().optional().describe(
1004
1000
  'Comma-separated glob pattern to filter files (e.g., "*.ts" for TypeScript files or "*.ts,*.js" for both TypeScript and JavaScript files). If not provided, it will search all files (*).'
1005
1001
  ).meta({
1006
1002
  usageValue: "file pattern here (optional)"
@@ -1027,7 +1023,7 @@ var toolInfo9 = {
1027
1023
  ],
1028
1024
  permissionLevel: 1 /* Read */
1029
1025
  };
1030
- var handler9 = async (provider, args) => {
1026
+ var handler12 = async (provider, args) => {
1031
1027
  if (!provider.searchFiles) {
1032
1028
  return {
1033
1029
  type: "Error" /* Error */,
@@ -1035,7 +1031,7 @@ var handler9 = async (provider, args) => {
1035
1031
  };
1036
1032
  }
1037
1033
  try {
1038
- const { path, regex, filePattern } = toolInfo9.parameters.parse(args);
1034
+ const { path, regex, filePattern } = toolInfo12.parameters.parse(args);
1039
1035
  const files = await provider.searchFiles(path, regex, filePattern ?? "*");
1040
1036
  return {
1041
1037
  type: "Reply" /* Reply */,
@@ -1054,23 +1050,23 @@ ${files.join("\n")}
1054
1050
  };
1055
1051
  }
1056
1052
  };
1057
- var isAvailable9 = (provider) => {
1053
+ var isAvailable12 = (provider) => {
1058
1054
  return !!provider.searchFiles;
1059
1055
  };
1060
1056
  var searchFiles_default = {
1061
- ...toolInfo9,
1062
- handler: handler9,
1063
- isAvailable: isAvailable9
1057
+ ...toolInfo12,
1058
+ handler: handler12,
1059
+ isAvailable: isAvailable12
1064
1060
  };
1065
1061
 
1066
1062
  // src/tools/writeToFile.ts
1067
- import { z as z10 } from "zod";
1068
- var toolInfo10 = {
1063
+ import { z as z13 } from "zod";
1064
+ var toolInfo13 = {
1069
1065
  name: "write_to_file",
1070
1066
  description: "Request to write content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file. Ensure that the output content does not include incorrect escaped character patterns such as `&lt;`, `&gt;`, or `&amp;`. Also ensure there is no unwanted CDATA tags in the content.",
1071
- parameters: z10.object({
1072
- path: z10.string().describe("The path of the file to write to").meta({ usageValue: "File path here" }),
1073
- content: z10.string().describe(
1067
+ parameters: z13.object({
1068
+ path: z13.string().describe("The path of the file to write to").meta({ usageValue: "File path here" }),
1069
+ content: z13.string().describe(
1074
1070
  "The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified."
1075
1071
  ).meta({ usageValue: "Your file content here" })
1076
1072
  }),
@@ -1102,14 +1098,14 @@ export default App;
1102
1098
  ],
1103
1099
  permissionLevel: 2 /* Write */
1104
1100
  };
1105
- var handler10 = async (provider, args) => {
1101
+ var handler13 = async (provider, args) => {
1106
1102
  if (!provider.writeFile) {
1107
1103
  return {
1108
1104
  type: "Error" /* Error */,
1109
1105
  message: "Not possible to write file. Abort."
1110
1106
  };
1111
1107
  }
1112
- const parsed = toolInfo10.parameters.safeParse(args);
1108
+ const parsed = toolInfo13.parameters.safeParse(args);
1113
1109
  if (!parsed.success) {
1114
1110
  return {
1115
1111
  type: "Invalid" /* Invalid */,
@@ -1125,179 +1121,44 @@ var handler10 = async (provider, args) => {
1125
1121
  message: `<write_to_file_path>${path}</write_to_file_path><status>Success</status>`
1126
1122
  };
1127
1123
  };
1128
- var isAvailable10 = (provider) => {
1124
+ var isAvailable13 = (provider) => {
1129
1125
  return !!provider.writeFile;
1130
1126
  };
1131
1127
  var writeToFile_default = {
1132
- ...toolInfo10,
1133
- handler: handler10,
1134
- isAvailable: isAvailable10
1128
+ ...toolInfo13,
1129
+ handler: handler13,
1130
+ isAvailable: isAvailable13
1135
1131
  };
1136
1132
 
1137
- // src/tools/handOver.ts
1138
- import { z as z11 } from "zod";
1139
- var toolInfo11 = {
1140
- name: "hand_over",
1141
- description: "Hand over the current task to another agent to complete. This tool MUST NOT to be used with any other tool.",
1142
- parameters: z11.object({
1143
- agentName: z11.string().describe("The name of the agent to hand over the task to").meta({ usageValue: "Name of the target agent" }),
1144
- task: z11.string().describe("The task to be completed by the target agent").meta({ usageValue: "Task description" }),
1145
- context: z11.string().describe("The context information for the task").meta({ usageValue: "Context information" }),
1146
- files: z11.preprocess((val) => {
1147
- if (!val) return [];
1148
- const values = Array.isArray(val) ? val : [val];
1149
- return values.flatMap((i) => typeof i === "string" ? i.split(",") : []).filter((s) => s.length > 0);
1150
- }, z11.array(z11.string())).optional().describe("The files relevant to the task. Comma separated paths").meta({ usageValue: "Relevant files" })
1151
- }),
1152
- examples: [
1153
- {
1154
- description: "Hand over a coding task to the coder agent",
1155
- parameters: [
1156
- {
1157
- name: "agentName",
1158
- value: "coder"
1159
- },
1160
- {
1161
- name: "task",
1162
- value: "Implement the login feature"
1163
- },
1164
- {
1165
- name: "context",
1166
- value: "We need a secure login system with email and password"
1167
- },
1168
- {
1169
- name: "files",
1170
- value: "src/auth/login.ts,src/auth/types.ts"
1171
- }
1172
- ]
1173
- }
1174
- ],
1175
- permissionLevel: 0 /* None */
1176
- };
1177
- var handler11 = async (_provider, args) => {
1178
- const parsed = toolInfo11.parameters.safeParse(args);
1179
- if (!parsed.success) {
1180
- return {
1181
- type: "Invalid" /* Invalid */,
1182
- message: `Invalid arguments for hand_over: ${parsed.error.message}`
1183
- };
1133
+ // src/tools/provider.ts
1134
+ var MockProvider = class {
1135
+ async readFile(_path) {
1136
+ return "mock content";
1184
1137
  }
1185
- const { agentName, task, context, files } = parsed.data;
1186
- return {
1187
- type: "HandOver" /* HandOver */,
1188
- agentName,
1189
- task,
1190
- context,
1191
- files: files ?? []
1192
- };
1193
- };
1194
- var isAvailable11 = (_provider) => {
1195
- return true;
1196
- };
1197
- var handOver_default = {
1198
- ...toolInfo11,
1199
- handler: handler11,
1200
- isAvailable: isAvailable11
1201
- };
1202
-
1203
- // src/tools/removeFile.ts
1204
- import { z as z12 } from "zod";
1205
- var toolInfo12 = {
1206
- name: "remove_file",
1207
- description: "Request to remove a file at the specified path.",
1208
- parameters: z12.object({
1209
- path: z12.string().describe("The path of the file to remove").meta({ usageValue: "File path here" })
1210
- }),
1211
- examples: [
1212
- {
1213
- description: "Request to remove a file",
1214
- parameters: [
1215
- {
1216
- name: "path",
1217
- value: "src/main.js"
1218
- }
1219
- ]
1220
- }
1221
- ],
1222
- permissionLevel: 2 /* Write */
1223
- };
1224
- var handler12 = async (provider, args) => {
1225
- if (!provider.removeFile) {
1226
- return {
1227
- type: "Error" /* Error */,
1228
- message: "Not possible to remove file. Abort."
1229
- };
1138
+ async writeFile(_path, _content) {
1139
+ return;
1230
1140
  }
1231
- const parsed = toolInfo12.parameters.safeParse(args);
1232
- if (!parsed.success) {
1233
- return {
1234
- type: "Invalid" /* Invalid */,
1235
- message: `Invalid arguments for remove_file: ${parsed.error.message}`
1236
- };
1141
+ async removeFile(_path) {
1142
+ return;
1237
1143
  }
1238
- const { path } = parsed.data;
1239
- await provider.removeFile(path);
1240
- return {
1241
- type: "Reply" /* Reply */,
1242
- message: `<remove_file_path>${path}</remove_file_path><status>Success</status>`
1243
- };
1244
- };
1245
- var isAvailable12 = (provider) => {
1246
- return !!provider.removeFile;
1247
- };
1248
- var removeFile_default = {
1249
- ...toolInfo12,
1250
- handler: handler12,
1251
- isAvailable: isAvailable12
1252
- };
1253
-
1254
- // src/tools/renameFile.ts
1255
- import { z as z13 } from "zod";
1256
- var toolInfo13 = {
1257
- name: "rename_file",
1258
- description: "Request to rename a file from source path to target path.",
1259
- parameters: z13.object({
1260
- source_path: z13.string().describe("The current path of the file").meta({ usageValue: "Source file path here" }),
1261
- target_path: z13.string().describe("The new path for the file").meta({ usageValue: "Target file path here" })
1262
- }),
1263
- examples: [
1264
- {
1265
- description: "Request to rename a file",
1266
- parameters: [
1267
- {
1268
- name: "source_path",
1269
- value: "src/old-name.js"
1270
- },
1271
- {
1272
- name: "target_path",
1273
- value: "src/new-name.js"
1274
- }
1275
- ]
1276
- }
1277
- ],
1278
- permissionLevel: 2 /* Write */
1279
- };
1280
- var handler13 = async (provider, args) => {
1281
- if (!provider.renameFile) {
1282
- return {
1283
- type: "Error" /* Error */,
1284
- message: "Not possible to rename file. Abort."
1285
- };
1144
+ async renameFile(_sourcePath, _targetPath) {
1145
+ return;
1146
+ }
1147
+ async listFiles(_path, _recursive, _maxCount) {
1148
+ return [["mock-file.txt"], false];
1149
+ }
1150
+ async searchFiles(_path, _regex, _filePattern) {
1151
+ return ["mock-file.txt"];
1152
+ }
1153
+ async executeCommand(_command, _needApprove) {
1154
+ return { stdout: "mock output", stderr: "", exitCode: 0 };
1155
+ }
1156
+ async askFollowupQuestion(_question, _options) {
1157
+ return "mock answer";
1158
+ }
1159
+ async attemptCompletion(_result) {
1160
+ return "mock completion";
1286
1161
  }
1287
- const { source_path, target_path } = toolInfo13.parameters.parse(args);
1288
- await provider.renameFile(source_path, target_path);
1289
- return {
1290
- type: "Reply" /* Reply */,
1291
- message: `<rename_file_path>${target_path}</rename_file_path><status>Success</status>`
1292
- };
1293
- };
1294
- var isAvailable13 = (provider) => {
1295
- return !!provider.renameFile;
1296
- };
1297
- var renameFile_default = {
1298
- ...toolInfo13,
1299
- handler: handler13,
1300
- isAvailable: isAvailable13
1301
1162
  };
1302
1163
 
1303
1164
  // src/getAvailableTools.ts
@@ -1365,6 +1226,150 @@ function toToolInfoV1(tool) {
1365
1226
  };
1366
1227
  }
1367
1228
 
1229
+ // src/UsageMeter.ts
1230
+ var UsageMeter = class {
1231
+ #totals = { input: 0, output: 0, cachedRead: 0, cost: 0 };
1232
+ #calls = 0;
1233
+ #modelInfos;
1234
+ #maxMessages;
1235
+ #maxCost;
1236
+ constructor(modelInfos = {}, opts = {}) {
1237
+ const infos = {};
1238
+ for (const [provider, providerInfo] of Object.entries(modelInfos)) {
1239
+ for (const [model, modelInfo] of Object.entries(providerInfo)) {
1240
+ infos[`${provider.split("-")[0]}:${model.replace(/[.-]/g, "")}`] = {
1241
+ inputPrice: modelInfo.inputPrice ?? 0,
1242
+ outputPrice: modelInfo.outputPrice ?? 0,
1243
+ cacheWritesPrice: modelInfo.cacheWritesPrice ?? 0,
1244
+ cacheReadsPrice: modelInfo.cacheReadsPrice ?? 0
1245
+ };
1246
+ }
1247
+ }
1248
+ this.#modelInfos = infos;
1249
+ this.#maxMessages = opts.maxMessages ?? 1e3;
1250
+ this.#maxCost = opts.maxCost ?? 100;
1251
+ }
1252
+ #calculageUsage(usage, providerMetadata, modelInfo) {
1253
+ const providerMetadataKey = Object.keys(providerMetadata ?? {})[0];
1254
+ const metadata = providerMetadata?.[providerMetadataKey] ?? {};
1255
+ switch (providerMetadataKey) {
1256
+ case "openrouter":
1257
+ return {
1258
+ input: usage.inputTokens ?? 0,
1259
+ output: usage.outputTokens ?? 0,
1260
+ cachedRead: usage.cachedInputTokens ?? 0,
1261
+ cost: metadata.usage?.cost ?? 0
1262
+ };
1263
+ case "anthropic": {
1264
+ const cachedRead = usage.cachedInputTokens ?? 0;
1265
+ const cacheWrite = metadata?.promptCacheMissTokens ?? 0;
1266
+ const input = usage.inputTokens ?? 0;
1267
+ const output = usage.outputTokens ?? 0;
1268
+ return {
1269
+ input: input + cacheWrite + cachedRead,
1270
+ output,
1271
+ cachedRead,
1272
+ cost: (input * modelInfo.inputPrice + output * modelInfo.outputPrice + cacheWrite * modelInfo.cacheWritesPrice + cachedRead * modelInfo.cacheReadsPrice) / 1e6
1273
+ };
1274
+ }
1275
+ case "deepseek": {
1276
+ const cachedRead = usage.cachedInputTokens ?? 0;
1277
+ const cacheWrite = metadata.promptCacheMissTokens ?? 0;
1278
+ const input = usage.inputTokens ?? 0;
1279
+ const output = usage.outputTokens ?? 0;
1280
+ return {
1281
+ input,
1282
+ output,
1283
+ cachedRead,
1284
+ cost: (output * modelInfo.outputPrice + cacheWrite * modelInfo.inputPrice + cachedRead * modelInfo.cacheReadsPrice) / 1e6
1285
+ };
1286
+ }
1287
+ default: {
1288
+ const cachedRead = usage.cachedInputTokens ?? 0;
1289
+ const input = usage.inputTokens ?? 0;
1290
+ const output = usage.outputTokens ?? 0;
1291
+ return {
1292
+ input,
1293
+ output,
1294
+ cachedRead,
1295
+ cost: (input * modelInfo.inputPrice + output * modelInfo.outputPrice) / 1e6
1296
+ };
1297
+ }
1298
+ }
1299
+ }
1300
+ addUsage(llm, resp, options = {}) {
1301
+ const modelInfo = options.modelInfo ?? // make google.vertex.chat to google
1302
+ // and anthropic.messages to anthropic
1303
+ this.#modelInfos[`${llm.provider.split(".")[0]}:${llm.modelId.replace(/[.-]/g, "")}`] ?? {
1304
+ inputPrice: 0,
1305
+ outputPrice: 0,
1306
+ cacheWritesPrice: 0,
1307
+ cacheReadsPrice: 0
1308
+ };
1309
+ const usage = "totalUsage" in resp ? resp.totalUsage : resp.usage;
1310
+ const result = this.#calculageUsage(usage, resp.providerMetadata, modelInfo);
1311
+ this.#totals.input += result.input;
1312
+ this.#totals.output += result.output;
1313
+ this.#totals.cachedRead += result.cachedRead;
1314
+ this.#totals.cost += result.cost;
1315
+ this.#calls++;
1316
+ }
1317
+ /** Override the running totals (e.g., restore from saved state). */
1318
+ setUsage(newUsage) {
1319
+ if (newUsage.input != null) this.#totals.input = newUsage.input;
1320
+ if (newUsage.output != null) this.#totals.output = newUsage.output;
1321
+ if (newUsage.cachedRead != null) this.#totals.cachedRead = newUsage.cachedRead;
1322
+ if (newUsage.cost != null) this.#totals.cost = newUsage.cost;
1323
+ if (newUsage.calls != null) this.#calls = newUsage.calls;
1324
+ }
1325
+ /** Manually bump the message count (useful if you record some calls without token info). */
1326
+ incrementMessageCount(n = 1) {
1327
+ this.#calls += n;
1328
+ }
1329
+ /** Reset the running totals. */
1330
+ resetUsage() {
1331
+ this.#totals = { input: 0, output: 0, cachedRead: 0, cost: 0 };
1332
+ this.#calls = 0;
1333
+ }
1334
+ /** Return true once either messages or cost exceed the configured caps. */
1335
+ isLimitExceeded() {
1336
+ const messageCount = this.#maxMessages !== void 0 && this.#calls >= this.#maxMessages;
1337
+ const cost = this.#maxCost !== void 0 && this.#totals.cost >= this.#maxCost;
1338
+ return {
1339
+ messageCount,
1340
+ maxMessages: this.#maxMessages,
1341
+ cost,
1342
+ maxCost: this.#maxCost,
1343
+ result: messageCount || cost
1344
+ };
1345
+ }
1346
+ /** Same as isLimitExceeded but throws an error if a limit is hit. */
1347
+ checkLimit() {
1348
+ const result = this.isLimitExceeded();
1349
+ if (result.result) {
1350
+ throw new Error(
1351
+ `Usage limit exceeded. Message count: ${result.messageCount}/${result.maxMessages}, cost: ${result.cost}/${result.maxCost}`
1352
+ );
1353
+ }
1354
+ }
1355
+ /** Getter for the aggregated totals (immutable copy). */
1356
+ get usage() {
1357
+ return { ...this.#totals, messageCount: this.#calls };
1358
+ }
1359
+ /** Print a concise usage summary to console. */
1360
+ printUsage() {
1361
+ const u = this.usage;
1362
+ console.log(
1363
+ `Usage - messages: ${u.messageCount}, input: ${u.input}, cached: ${u.cachedRead}, output: ${u.output}, cost: $${u.cost.toFixed(4)}`
1364
+ );
1365
+ }
1366
+ onFinishHandler(llm) {
1367
+ return (evt) => {
1368
+ this.addUsage(llm, evt);
1369
+ };
1370
+ }
1371
+ };
1372
+
1368
1373
  // src/Agent/AgentBase.ts
1369
1374
  import { streamText } from "ai";
1370
1375
 
@@ -1641,7 +1646,7 @@ ${agent.responsibilities.map((resp) => ` - ${resp}`).join("\n")}`
1641
1646
  - **Current Agent Role**
1642
1647
  You are currently acting as **${name}**. If you identify the task is beyond your current scope, use the handover or delegate tool to transition to the other agent. Include sufficient context so the new agent can seamlessly continue the work.
1643
1648
  `;
1644
- var capabilities = (toolNamePrefix) => `
1649
+ var capabilities = (_toolNamePrefix) => `
1645
1650
  ====
1646
1651
 
1647
1652
  CAPABILITIES
@@ -2327,7 +2332,7 @@ RETRY GUIDELINES
2327
2332
  - Explain why the issue remains
2328
2333
  - Suggest manual intervention steps
2329
2334
  - Report any partial improvements`;
2330
- var fullSystemPrompt3 = (info, tools, toolNamePrefix, instructions, scripts, interactive, useNativeTool) => `
2335
+ var fullSystemPrompt3 = (info, tools, toolNamePrefix, instructions, scripts, _interactive, useNativeTool) => `
2331
2336
  ${basePrompt}
2332
2337
  ${useNativeTool ? "" : toolUsePrompt(tools, toolNamePrefix)}
2333
2338
  ${codeFixingStrategies}
@@ -2378,7 +2383,7 @@ var CodeFixerAgent = class extends AgentBase {
2378
2383
  });
2379
2384
  this.#maxRetries = options.maxRetries ?? 5;
2380
2385
  }
2381
- async onBeforeInvokeTool(name, args) {
2386
+ async onBeforeInvokeTool(name, _args) {
2382
2387
  if (name === attemptCompletion_default.name) {
2383
2388
  if (this.#retryCount > this.#maxRetries) {
2384
2389
  return;
@@ -2582,7 +2587,7 @@ var CoderAgent = class extends AgentBase {
2582
2587
  usageMeter: options.usageMeter ?? new UsageMeter()
2583
2588
  });
2584
2589
  }
2585
- async onBeforeInvokeTool(name, args) {
2590
+ async onBeforeInvokeTool(name, _args) {
2586
2591
  if (name !== attemptCompletion_default.name) {
2587
2592
  return;
2588
2593
  }
@@ -2762,7 +2767,10 @@ var configSchema = z15.object({
2762
2767
  z15.object({
2763
2768
  apiKey: z15.string().optional(),
2764
2769
  defaultModel: z15.string().optional(),
2765
- defaultParameters: z15.record(z15.string(), z15.any()).optional()
2770
+ defaultParameters: z15.record(z15.string(), z15.any()).optional(),
2771
+ location: z15.string().optional(),
2772
+ project: z15.string().optional(),
2773
+ keyFile: z15.string().optional()
2766
2774
  })
2767
2775
  ).optional(),
2768
2776
  defaultProvider: z15.string().optional(),
@@ -2796,6 +2804,58 @@ var Policies = /* @__PURE__ */ ((Policies2) => {
2796
2804
  return Policies2;
2797
2805
  })(Policies || {});
2798
2806
 
2807
+ // src/Agent/policies/EnableCachePolicy.ts
2808
+ var CACHEABLE_MODELS = ["sonnet", "opus", "haiku", "gemini"];
2809
+ function isCacheableModel(modelId) {
2810
+ return CACHEABLE_MODELS.some((model) => modelId.includes(model));
2811
+ }
2812
+ function getProviderKey(provider) {
2813
+ if (provider === "openrouter") {
2814
+ return "openrouter";
2815
+ }
2816
+ if (provider.includes("anthropic")) {
2817
+ return "anthropic";
2818
+ }
2819
+ return void 0;
2820
+ }
2821
+ var EnableCachePolicy = () => {
2822
+ return {
2823
+ name: "enablecache" /* EnableCache */,
2824
+ async prepareMessages(agent, messages) {
2825
+ const providerKey = getProviderKey(agent.ai.provider);
2826
+ if (!providerKey || !isCacheableModel(agent.ai.modelId)) {
2827
+ return messages;
2828
+ }
2829
+ const providerOptions = { [providerKey]: { cacheControl: { type: "ephemeral" } } };
2830
+ const newMessages = messages.slice();
2831
+ let userMessagesToUpdate = 2;
2832
+ for (let i = newMessages.length - 1; i >= 0; i--) {
2833
+ const message = newMessages[i];
2834
+ if (message.role === "user" && userMessagesToUpdate > 0) {
2835
+ newMessages[i] = {
2836
+ ...message,
2837
+ providerOptions: {
2838
+ ...providerOptions,
2839
+ ...message.providerOptions ?? {}
2840
+ }
2841
+ };
2842
+ userMessagesToUpdate--;
2843
+ } else if (message.role === "system") {
2844
+ newMessages[i] = {
2845
+ ...message,
2846
+ providerOptions: {
2847
+ ...providerOptions,
2848
+ ...message.providerOptions ?? {}
2849
+ }
2850
+ };
2851
+ break;
2852
+ }
2853
+ }
2854
+ return newMessages;
2855
+ }
2856
+ };
2857
+ };
2858
+
2799
2859
  // src/Agent/policies/TruncateContextPolicy.ts
2800
2860
  var DEFAULT_MAX_TOKENS_ESTIMATE = 32e3;
2801
2861
  function getMaxTokens(agent) {
@@ -2893,58 +2953,6 @@ var TruncateContextPolicy = () => {
2893
2953
  };
2894
2954
  };
2895
2955
 
2896
- // src/Agent/policies/EnableCachePolicy.ts
2897
- var CACHEABLE_MODELS = ["sonnet", "opus", "haiku", "gemini"];
2898
- function isCacheableModel(modelId) {
2899
- return CACHEABLE_MODELS.some((model) => modelId.includes(model));
2900
- }
2901
- function getProviderKey(provider) {
2902
- if (provider === "openrouter") {
2903
- return "openrouter";
2904
- }
2905
- if (provider.includes("anthropic")) {
2906
- return "anthropic";
2907
- }
2908
- return void 0;
2909
- }
2910
- var EnableCachePolicy = () => {
2911
- return {
2912
- name: "enablecache" /* EnableCache */,
2913
- async prepareMessages(agent, messages) {
2914
- const providerKey = getProviderKey(agent.ai.provider);
2915
- if (!providerKey || !isCacheableModel(agent.ai.modelId)) {
2916
- return messages;
2917
- }
2918
- const providerOptions = { [providerKey]: { cacheControl: { type: "ephemeral" } } };
2919
- const newMessages = messages.slice();
2920
- let userMessagesToUpdate = 2;
2921
- for (let i = newMessages.length - 1; i >= 0; i--) {
2922
- const message = newMessages[i];
2923
- if (message.role === "user" && userMessagesToUpdate > 0) {
2924
- newMessages[i] = {
2925
- ...message,
2926
- providerOptions: {
2927
- ...providerOptions,
2928
- ...message.providerOptions ?? {}
2929
- }
2930
- };
2931
- userMessagesToUpdate--;
2932
- } else if (message.role === "system") {
2933
- newMessages[i] = {
2934
- ...message,
2935
- providerOptions: {
2936
- ...providerOptions,
2937
- ...message.providerOptions ?? {}
2938
- }
2939
- };
2940
- break;
2941
- }
2942
- }
2943
- return newMessages;
2944
- }
2945
- };
2946
- };
2947
-
2948
2956
  // src/Agent/index.ts
2949
2957
  var allAgents = [architectAgentInfo, coderAgentInfo, analyzerAgentInfo, codeFixerAgentInfo];
2950
2958