@tyvm/knowhow 0.0.127 → 0.0.129

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 (109) hide show
  1. package/package.json +2 -1
  2. package/scripts/cache-miss-debug.ts +365 -0
  3. package/src/agents/base/base.ts +119 -54
  4. package/src/agents/tools/execCommand.ts +38 -4
  5. package/src/agents/tools/minimal/callTool.ts +45 -0
  6. package/src/agents/tools/minimal/definitions.ts +50 -0
  7. package/src/agents/tools/minimal/index.ts +3 -0
  8. package/src/agents/tools/minimal/inspectTools.ts +27 -0
  9. package/src/chat/modules/AgentModule.ts +27 -8
  10. package/src/clients/contextLimits.ts +9 -0
  11. package/src/clients/index.ts +6 -0
  12. package/src/clients/meta.ts +18 -0
  13. package/src/clients/pricing/anthropic.ts +13 -0
  14. package/src/clients/pricing/fireworks.ts +18 -12
  15. package/src/clients/pricing/index.ts +1 -0
  16. package/src/clients/pricing/meta.ts +12 -0
  17. package/src/clients/pricing/openai.ts +13 -0
  18. package/src/clients/pricing/xai.ts +3 -0
  19. package/src/commands/services.ts +1 -1
  20. package/src/processors/MinimalToolsMessageProcessor.ts +113 -0
  21. package/src/processors/TokenCompressor.ts +21 -4
  22. package/src/processors/index.ts +7 -1
  23. package/src/services/AgentSyncFs.ts +49 -0
  24. package/src/services/AgentSyncKnowhowWeb.ts +1 -1
  25. package/src/services/KnowhowClient.ts +1 -1
  26. package/src/services/LazyToolsService.ts +12 -0
  27. package/src/services/MinimalToolsService.ts +167 -0
  28. package/src/services/Tools.ts +9 -0
  29. package/src/services/index.ts +1 -0
  30. package/src/worker.ts +7 -0
  31. package/tests/processors/TokenCompressor.test.ts +45 -0
  32. package/tests/unit/services/MinimalToolsService.test.ts +424 -0
  33. package/ts_build/package.json +2 -1
  34. package/ts_build/src/agents/base/base.d.ts +4 -1
  35. package/ts_build/src/agents/base/base.js +62 -31
  36. package/ts_build/src/agents/base/base.js.map +1 -1
  37. package/ts_build/src/agents/tools/execCommand.d.ts +1 -1
  38. package/ts_build/src/agents/tools/execCommand.js +24 -3
  39. package/ts_build/src/agents/tools/execCommand.js.map +1 -1
  40. package/ts_build/src/agents/tools/minimal/callTool.d.ts +5 -0
  41. package/ts_build/src/agents/tools/minimal/callTool.js +28 -0
  42. package/ts_build/src/agents/tools/minimal/callTool.js.map +1 -0
  43. package/ts_build/src/agents/tools/minimal/definitions.d.ts +4 -0
  44. package/ts_build/src/agents/tools/minimal/definitions.js +46 -0
  45. package/ts_build/src/agents/tools/minimal/definitions.js.map +1 -0
  46. package/ts_build/src/agents/tools/minimal/index.d.ts +3 -0
  47. package/ts_build/src/agents/tools/minimal/index.js +20 -0
  48. package/ts_build/src/agents/tools/minimal/index.js.map +1 -0
  49. package/ts_build/src/agents/tools/minimal/inspectTools.d.ts +2 -0
  50. package/ts_build/src/agents/tools/minimal/inspectTools.js +15 -0
  51. package/ts_build/src/agents/tools/minimal/inspectTools.js.map +1 -0
  52. package/ts_build/src/chat/modules/AgentModule.js +8 -2
  53. package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
  54. package/ts_build/src/clients/contextLimits.js +8 -0
  55. package/ts_build/src/clients/contextLimits.js.map +1 -1
  56. package/ts_build/src/clients/index.d.ts +1 -0
  57. package/ts_build/src/clients/index.js +6 -0
  58. package/ts_build/src/clients/index.js.map +1 -1
  59. package/ts_build/src/clients/meta.d.ts +4 -0
  60. package/ts_build/src/clients/meta.js +15 -0
  61. package/ts_build/src/clients/meta.js.map +1 -0
  62. package/ts_build/src/clients/pricing/anthropic.d.ts +4 -0
  63. package/ts_build/src/clients/pricing/anthropic.js +12 -0
  64. package/ts_build/src/clients/pricing/anthropic.js.map +1 -1
  65. package/ts_build/src/clients/pricing/fireworks.d.ts +2 -5
  66. package/ts_build/src/clients/pricing/fireworks.js +13 -11
  67. package/ts_build/src/clients/pricing/fireworks.js.map +1 -1
  68. package/ts_build/src/clients/pricing/index.d.ts +1 -0
  69. package/ts_build/src/clients/pricing/index.js +5 -2
  70. package/ts_build/src/clients/pricing/index.js.map +1 -1
  71. package/ts_build/src/clients/pricing/meta.d.ts +6 -0
  72. package/ts_build/src/clients/pricing/meta.js +8 -0
  73. package/ts_build/src/clients/pricing/meta.js.map +1 -0
  74. package/ts_build/src/clients/pricing/openai.d.ts +3 -0
  75. package/ts_build/src/clients/pricing/openai.js +12 -0
  76. package/ts_build/src/clients/pricing/openai.js.map +1 -1
  77. package/ts_build/src/clients/pricing/xai.d.ts +1 -0
  78. package/ts_build/src/clients/pricing/xai.js +3 -0
  79. package/ts_build/src/clients/pricing/xai.js.map +1 -1
  80. package/ts_build/src/commands/services.js.map +1 -1
  81. package/ts_build/src/processors/MinimalToolsMessageProcessor.d.ts +7 -0
  82. package/ts_build/src/processors/MinimalToolsMessageProcessor.js +61 -0
  83. package/ts_build/src/processors/MinimalToolsMessageProcessor.js.map +1 -0
  84. package/ts_build/src/processors/TokenCompressor.js +5 -2
  85. package/ts_build/src/processors/TokenCompressor.js.map +1 -1
  86. package/ts_build/src/processors/index.d.ts +2 -1
  87. package/ts_build/src/processors/index.js +3 -1
  88. package/ts_build/src/processors/index.js.map +1 -1
  89. package/ts_build/src/services/AgentSyncFs.d.ts +2 -0
  90. package/ts_build/src/services/AgentSyncFs.js +30 -0
  91. package/ts_build/src/services/AgentSyncFs.js.map +1 -1
  92. package/ts_build/src/services/AgentSyncKnowhowWeb.js +1 -1
  93. package/ts_build/src/services/KnowhowClient.d.ts +1 -1
  94. package/ts_build/src/services/LazyToolsService.js.map +1 -1
  95. package/ts_build/src/services/MinimalToolsService.d.ts +14 -0
  96. package/ts_build/src/services/MinimalToolsService.js +80 -0
  97. package/ts_build/src/services/MinimalToolsService.js.map +1 -0
  98. package/ts_build/src/services/Tools.js.map +1 -1
  99. package/ts_build/src/services/index.d.ts +1 -0
  100. package/ts_build/src/services/index.js +1 -0
  101. package/ts_build/src/services/index.js.map +1 -1
  102. package/ts_build/src/types.d.ts +8 -0
  103. package/ts_build/src/worker.js +5 -0
  104. package/ts_build/src/worker.js.map +1 -1
  105. package/ts_build/tests/processors/TokenCompressor.test.js +27 -0
  106. package/ts_build/tests/processors/TokenCompressor.test.js.map +1 -1
  107. package/ts_build/tests/unit/services/MinimalToolsService.test.d.ts +1 -0
  108. package/ts_build/tests/unit/services/MinimalToolsService.test.js +320 -0
  109. package/ts_build/tests/unit/services/MinimalToolsService.test.js.map +1 -0
@@ -259,7 +259,7 @@ const execWithTimeout = async (
259
259
  // Public tool
260
260
  export async function execCommand(
261
261
  command: string,
262
- timeout?: number,
262
+ timeout?: number | string,
263
263
  continueInBackground?: boolean,
264
264
  logFileName?: string
265
265
  ): Promise<string> {
@@ -271,6 +271,40 @@ export async function execCommand(
271
271
  const toolService = (
272
272
  this instanceof ToolsService ? this : services().Tools
273
273
  ) as ToolsService;
274
+
275
+ // Coerce timeout to a number. Agents (and some tool-call serializers) often
276
+ // pass numeric arguments as strings (e.g. "120000"). Node's exec()/setTimeout
277
+ // reject non-integer values with "The value of \"timeout\" is out of range.
278
+ // It must be an unsigned integer", so normalize here before any use.
279
+ let normalizedTimeout: number | undefined;
280
+ const rawTimeout = typeof timeout === "string" ? Number(timeout.trim()) : timeout;
281
+ if (typeof rawTimeout !== "number" || !Number.isFinite(rawTimeout)) {
282
+ normalizedTimeout = undefined;
283
+ } else if (rawTimeout === -1) {
284
+ // -1 is the sentinel for "wait indefinitely" — leave as-is.
285
+ normalizedTimeout = -1;
286
+ } else {
287
+ // Clamp to a non-negative integer so the underlying APIs never throw.
288
+ normalizedTimeout = Math.max(0, Math.floor(rawTimeout));
289
+ }
290
+
291
+ // Detect suspiciously small timeout values — agents often pass seconds instead of ms.
292
+ // Any value < 100 is almost certainly a mistake (100ms is still very fast for a shell cmd).
293
+ // We auto-correct to seconds and include a warning in the output so the agent learns.
294
+ let correctedTimeout = normalizedTimeout;
295
+ let timeoutWarning = "";
296
+ if (
297
+ normalizedTimeout !== undefined &&
298
+ normalizedTimeout !== -1 &&
299
+ normalizedTimeout < 100
300
+ ) {
301
+ correctedTimeout = normalizedTimeout * 1000;
302
+ timeoutWarning =
303
+ `⚠️ Warning: timeout was ${normalizedTimeout}ms which is extremely small and likely a mistake. ` +
304
+ `The timeout unit is milliseconds, not seconds. ` +
305
+ `Auto-corrected to ${correctedTimeout}ms (${normalizedTimeout}s).\n\n`;
306
+ }
307
+
274
308
  const context = toolService.getContext();
275
309
 
276
310
  // Emit pre-run blocking event — handlers can throw to block the command
@@ -285,7 +319,7 @@ export async function execCommand(
285
319
 
286
320
  const { stdout, stderr, timedOut, killed, pid, logPath } =
287
321
  await execWithTimeout(command, {
288
- timeout,
322
+ timeout: correctedTimeout,
289
323
  continueInBackground,
290
324
  logFileName,
291
325
  });
@@ -302,8 +336,8 @@ export async function execCommand(
302
336
  })`
303
337
  : "";
304
338
 
305
- const lines = output.split("\n");
306
339
  /*
340
+ *const lines = output.split("\n");
307
341
  *const maxLines = 1000;
308
342
  *const maxChars = 40000;
309
343
  *const trimmed = (lines.length > maxLines ? lines.slice(0, maxLines) : lines)
@@ -342,5 +376,5 @@ export async function execCommand(
342
376
  "\n\nAdditional Information:\n" + JSON.stringify(eventResults, null, 2);
343
377
  }
344
378
 
345
- return result + eventResultsText;
379
+ return timeoutWarning + result + eventResultsText;
346
380
  };
@@ -0,0 +1,45 @@
1
+ import { minimatch } from "minimatch";
2
+ import { MinimalToolsService } from "../../../services/MinimalToolsService";
3
+ import { ToolsService } from "../../../services/Tools";
4
+
5
+ /**
6
+ * Calls any tool by name with the given args.
7
+ * This is the escape hatch that lets agents call tools outside the base tool set
8
+ * without changing the `tools:` array sent to the AI (preserving cache stability).
9
+ */
10
+ export async function callTool(
11
+ this: ToolsService,
12
+ args: { name: string; args: Record<string, any> }
13
+ ): Promise<any> {
14
+ const service = this as unknown as MinimalToolsService;
15
+ const { name, args: toolArgs } = args;
16
+
17
+ const allTools = service.getAllTools ? service.getAllTools() : service.getTools();
18
+
19
+ // Fuzzy match: exact, endsWith, or glob
20
+ const matchedTool =
21
+ allTools.find((t) => t.function.name === name) ||
22
+ allTools.find((t) => t.function.name.endsWith(name)) ||
23
+ allTools.find((t) => minimatch(t.function.name, name, { nocase: true }));
24
+
25
+ if (!matchedTool) {
26
+ const available = allTools.map((t) => t.function.name).join(", ");
27
+ return `Error: Tool "${name}" not found. Use inspectTools() to browse available tools. Available: ${available}`;
28
+ }
29
+
30
+ const toolName = matchedTool.function.name;
31
+
32
+ // Build a synthetic ToolCall object and delegate to the base callTool
33
+ const syntheticToolCall = {
34
+ id: `call_minimal_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`,
35
+ type: "function" as const,
36
+ function: {
37
+ name: toolName,
38
+ arguments: JSON.stringify(toolArgs),
39
+ },
40
+ };
41
+
42
+ // Use base ToolsService.callTool with the matched tool name allowed
43
+ const result = await service.callToolByName(syntheticToolCall, toolName);
44
+ return result;
45
+ }
@@ -0,0 +1,50 @@
1
+ import { Tool } from "../../../clients/types";
2
+
3
+ export const callToolDefinition: Tool = {
4
+ type: "function",
5
+ function: {
6
+ name: "callTool",
7
+ description:
8
+ "Call any available tool by name with the given arguments. Use listStoredToolResponses + inspectTools to discover available tools and their argument schemas before calling. This is the primary way to call tools that are not in the base tool set.",
9
+ parameters: {
10
+ type: "object",
11
+ positional: false,
12
+ properties: {
13
+ name: {
14
+ type: "string",
15
+ description: "The name of the tool to call.",
16
+ },
17
+ args: {
18
+ type: "object",
19
+ description:
20
+ "The arguments to pass to the tool. Should match the tool's parameter schema.",
21
+ },
22
+ },
23
+ required: ["name", "args"],
24
+ },
25
+ },
26
+ };
27
+
28
+ export const inspectToolsDefinition: Tool = {
29
+ type: "function",
30
+ function: {
31
+ name: "inspectTools",
32
+ description:
33
+ "Get the full schema/definition for tools matching the given glob patterns. Use this to discover what arguments a tool needs before calling it via callTool. Example patterns: ['read*'] finds tools starting with 'read', ['*File'] finds tools ending with 'File'.",
34
+ parameters: {
35
+ type: "object",
36
+ positional: true,
37
+ properties: {
38
+ patterns: {
39
+ type: "array",
40
+ items: { type: "string" },
41
+ description:
42
+ "Array of glob patterns to filter tool names. If omitted, returns all available tools.",
43
+ },
44
+ },
45
+ required: [],
46
+ },
47
+ },
48
+ };
49
+
50
+ export const minimalDefinitions = [callToolDefinition, inspectToolsDefinition];
@@ -0,0 +1,3 @@
1
+ export * from "./callTool";
2
+ export * from "./inspectTools";
3
+ export * from "./definitions";
@@ -0,0 +1,27 @@
1
+ import { minimatch } from "minimatch";
2
+ import { MinimalToolsService } from "../../../services/MinimalToolsService";
3
+ import { ToolsService } from "../../../services/Tools";
4
+
5
+ /**
6
+ * Returns the full tool definitions (schema) for all tools matching the given patterns.
7
+ * Used by agents to discover argument shapes before calling via callTool.
8
+ */
9
+ export function inspectTools(
10
+ this: ToolsService,
11
+ patterns?: string[]
12
+ ): object[] {
13
+ const service = this as unknown as MinimalToolsService;
14
+ const allTools = service.getAllTools ? service.getAllTools() : service.getTools();
15
+
16
+ if (!patterns || patterns.length === 0) {
17
+ return allTools.map((t) => t.function);
18
+ }
19
+
20
+ return allTools
21
+ .filter((t) =>
22
+ patterns.some((pattern) =>
23
+ minimatch(t.function.name, pattern, { nocase: true })
24
+ )
25
+ )
26
+ .map((t) => t.function);
27
+ }
@@ -28,6 +28,7 @@ import {
28
28
  XmlToolCallProcessor,
29
29
  HarmonyToolProcessor,
30
30
  Base64ImageProcessor,
31
+ MinimalToolsMessageProcessor,
31
32
  } from "../../processors/index";
32
33
  import { TaskInfo } from "../types";
33
34
  import { createAgent, agentConstructors, AgentName } from "../../agents";
@@ -124,13 +125,16 @@ export class AgentModule extends BaseChatModule {
124
125
  },
125
126
  {
126
127
  name: "poke",
127
- description: "Interrupt the agent's current tool call or AI completion, so it can continue with the next step",
128
+ description:
129
+ "Interrupt the agent's current tool call or AI completion, so it can continue with the next step",
128
130
  modes: ["agent:attached"],
129
131
  handler: async (args: string[]): Promise<void> => {
130
132
  if (this.attachedAgent) {
131
133
  const message = args.length > 0 ? args.join(" ") : undefined;
132
134
  this.attachedAgent.interrupt(message);
133
- console.log("Agent interrupted — it will continue with the next step.");
135
+ console.log(
136
+ "Agent interrupted — it will continue with the next step."
137
+ );
134
138
  }
135
139
  },
136
140
  },
@@ -531,10 +535,14 @@ export class AgentModule extends BaseChatModule {
531
535
  const threads = session.threads || [];
532
536
  // Guard against sessions saved with a flat Message[] instead of Message[][]
533
537
  // (a bug where threadUpdate emitted a single thread instead of all threads)
534
- const normalizedThreads: Message[][] = threads.length > 0 && !Array.isArray(threads[0])
535
- ? [threads as unknown as Message[]]
536
- : threads as Message[][];
537
- const lastThread = normalizedThreads.length > 0 ? normalizedThreads[normalizedThreads.length - 1] : [];
538
+ const normalizedThreads: Message[][] =
539
+ threads.length > 0 && !Array.isArray(threads[0])
540
+ ? [threads as unknown as Message[]]
541
+ : (threads as Message[][]);
542
+ const lastThread =
543
+ normalizedThreads.length > 0
544
+ ? normalizedThreads[normalizedThreads.length - 1]
545
+ : [];
538
546
  const resumeMessages = [...lastThread];
539
547
 
540
548
  // Append the resume prompt to the last user message (or add a new one)
@@ -548,7 +556,9 @@ export class AgentModule extends BaseChatModule {
548
556
  const actualIndex = lastThread.length - 1 - reversedIndex;
549
557
  resumeMessages[actualIndex] = {
550
558
  ...resumeMessages[actualIndex],
551
- content: resumeMessages[actualIndex].content + `\n\n<Workflow>[RESUME CONTEXT]: ${resumePrompt}</Workflow>`,
559
+ content:
560
+ resumeMessages[actualIndex].content +
561
+ `\n\n<Workflow>[RESUME CONTEXT]: ${resumePrompt}</Workflow>`,
552
562
  };
553
563
  }
554
564
 
@@ -584,7 +594,12 @@ export class AgentModule extends BaseChatModule {
584
594
  }
585
595
  });
586
596
 
587
- await this.attachedAgentChatLoop(taskId, agent, resumePrompt, resumeMessages);
597
+ await this.attachedAgentChatLoop(
598
+ taskId,
599
+ agent,
600
+ resumePrompt,
601
+ resumeMessages
602
+ );
588
603
  } catch (error) {
589
604
  console.error(
590
605
  `Failed to resume session ${sessionId}:`,
@@ -781,6 +796,10 @@ export class AgentModule extends BaseChatModule {
781
796
  new HarmonyToolProcessor().createProcessor(),
782
797
  ]);
783
798
 
799
+ agent.messageProcessor.setProcessors("pre_tools", [
800
+ new MinimalToolsMessageProcessor().createProcessor(),
801
+ ]);
802
+
784
803
  agent.messageProcessor.setProcessors("post_tools", [
785
804
  new Base64ImageProcessor(agent.tools).createProcessor(),
786
805
  ...caching,
@@ -10,6 +10,9 @@ import { Models, EmbeddingModels } from "../types";
10
10
  */
11
11
  export const ContextLimits: Record<string, number> = {
12
12
  // ─── OpenAI ───────────────────────────────────────────────────────────────
13
+ [Models.openai.GPT_56_Sol]: 1_000_000,
14
+ [Models.openai.GPT_56_Terra]: 1_000_000,
15
+ [Models.openai.GPT_56_Luna]: 1_000_000,
13
16
  [Models.openai.GPT_55]: 1_000_000,
14
17
  [Models.openai.GPT_54]: 1_000_000,
15
18
  [Models.openai.GPT_54_Mini]: 400_000,
@@ -83,6 +86,11 @@ export const ContextLimits: Record<string, number> = {
83
86
  // ─── Anthropic ────────────────────────────────────────────────────────────
84
87
  [Models.anthropic.Opus4_8Fast]: 1_000_000,
85
88
  [Models.anthropic.Opus4_8]: 1_000_000,
89
+ // Claude 5 generation (launched 2026-06-09, 1M context window)
90
+ [Models.anthropic.Fable5]: 1_000_000,
91
+ [Models.anthropic.Sonnet5]: 1_000_000,
92
+ [Models.anthropic.Mythos5]: 1_000_000,
93
+ [Models.anthropic.MythosPreview]: 1_000_000,
86
94
  [Models.anthropic.Opus4_7]: 1_000_000,
87
95
  [Models.anthropic.Opus4_6]: 1_000_000,
88
96
  [Models.anthropic.Opus4_6Fast]: 1_000_000,
@@ -166,6 +174,7 @@ export const ContextLimits: Record<string, number> = {
166
174
  [Models.xai.GrokBeta]: 131_072,
167
175
  [Models.xai.GrokVisionBeta]: 131_072,
168
176
  [Models.xai.Grok4_1_Fast]: 2_000_000,
177
+ [Models.xai.Grok4_5]: 500_000,
169
178
  [Models.xai.Grok4Fast]: 2_000_000,
170
179
  [Models.xai.Grok4FastNonReasoning]: 2_000_000,
171
180
  // xAI image/video models — no text context window
@@ -41,6 +41,7 @@ import {
41
41
  XaiImagePricing,
42
42
  XaiVideoPricing,
43
43
  } from "./pricing/xai";
44
+ import { MetaTextPricing } from "./pricing/meta";
44
45
  import type {
45
46
  ModelPricing,
46
47
  ModelType,
@@ -56,6 +57,7 @@ import { GenericMistralClient } from "./mistral";
56
57
  import { GitHubCopilotClient } from "./copilot";
57
58
  import { GenericLlamaClient } from "./llama";
58
59
  import { GenericFireworksClient } from "./fireworks";
60
+ import { GenericMetaClient } from "./meta";
59
61
  export {
60
62
  OpenAiTextPricing,
61
63
  AnthropicTextPricing,
@@ -100,6 +102,7 @@ const BUILT_IN_PROVIDER_REGISTRY: Record<string, ProviderRegistryEntry> = {
100
102
  "github-copilot": { clientClass: GitHubCopilotClient },
101
103
  llama: { clientClass: GenericLlamaClient },
102
104
  fireworks: { clientClass: GenericFireworksClient },
105
+ meta: { clientClass: GenericMetaClient },
103
106
  knowhow: {
104
107
  createClient: (entry: ModelProvider) => {
105
108
  const jwt = loadKnowhowJwt();
@@ -130,6 +133,7 @@ const DEFAULT_PROVIDERS: ModelProvider[] = [
130
133
  { provider: "github-copilot", envKey: "GITHUB_COPILOT_TOKEN" },
131
134
  { provider: "llama", envKey: "LLAMA_API_KEY" },
132
135
  { provider: "fireworks", envKey: "FIREWORKS_API_KEY" },
136
+ { provider: "meta", envKey: "META_API_KEY" },
133
137
  ];
134
138
 
135
139
  export class AIClient {
@@ -1021,6 +1025,7 @@ export class AIClient {
1021
1025
  ...GeminiPricing,
1022
1026
  ...XaiTextPricing,
1023
1027
  ...FireworksTextPricing,
1028
+ ...MetaTextPricing,
1024
1029
  };
1025
1030
  const allImagePricing: Record<string, ModelPricing> = {
1026
1031
  ...XaiImagePricing,
@@ -1066,3 +1071,4 @@ export * from "./mistral";
1066
1071
  export * from "./llama";
1067
1072
  export * from "./copilot";
1068
1073
  export * from "./fireworks";
1074
+ export * from "./meta";
@@ -0,0 +1,18 @@
1
+ import { HttpClient } from "./http";
2
+ import { MetaTextPricing } from "./pricing/meta";
3
+
4
+ /**
5
+ * Meta Model API client — OpenAI-compatible API
6
+ * https://api.meta.ai
7
+ * Drop-in compatible with the OpenAI SDK (Responses + Chat Completions) and
8
+ * the Anthropic SDK (Messages API). Serves Meta's Muse Spark model with a
9
+ * 1,048,576 token context window.
10
+ * Set env var META_API_KEY to enable.
11
+ */
12
+ export class GenericMetaClient extends HttpClient {
13
+ constructor(apiKey = process.env.META_API_KEY) {
14
+ super("https://api.meta.ai");
15
+ if (apiKey) this.setJwt(apiKey);
16
+ this.setPrices(MetaTextPricing);
17
+ }
18
+ }
@@ -9,6 +9,10 @@ import { completions, ModelCatalogEntry, ModelPricing } from "./types";
9
9
 
10
10
  export const AnthropicModels = {
11
11
  // Active models
12
+ Fable5: "claude-fable-5",
13
+ Sonnet5: "claude-sonnet-5",
14
+ Mythos5: "claude-mythos-5",
15
+ MythosPreview: "claude-mythos-preview",
12
16
  Opus4_8: "claude-opus-4-8",
13
17
  Opus4_8Fast: "claude-opus-4-8-fast",
14
18
  Opus4_7: "claude-opus-4-7",
@@ -39,6 +43,8 @@ export const AnthropicModels = {
39
43
 
40
44
  export const AnthropicTextModels: string[] = [
41
45
  AnthropicModels.Opus4_8,
46
+ AnthropicModels.Fable5,
47
+ AnthropicModels.Sonnet5,
42
48
  AnthropicModels.Opus4_7,
43
49
  AnthropicModels.Opus4_6,
44
50
  AnthropicModels.Sonnet4_6,
@@ -51,6 +57,8 @@ export const AnthropicTextModels: string[] = [
51
57
  // Models in our catalog but not yet publicly available
52
58
  export const AnthropicLimitedAvailabilityModels: string[] = [
53
59
  AnthropicModels.Opus4_8Fast, // fast mode pricing
60
+ AnthropicModels.Mythos5, // invitation-only (Project Glasswing)
61
+ AnthropicModels.MythosPreview, // invitation-only (defensive cybersecurity)
54
62
  AnthropicModels.Opus4_6Fast, // 404 – not publicly available yet
55
63
  ];
56
64
 
@@ -80,6 +88,11 @@ const AnthropicAllModels: string[] = [
80
88
  export const AnthropicTextPricing: Record<string, ModelPricing> = {
81
89
  [AnthropicModels.Opus4_8]: { input: 5.0, cache_write: 6.25, cache_hit: 0.5, output: 25.0 },
82
90
  [AnthropicModels.Opus4_8Fast]: { input: 10.0, cache_write: 12.5, cache_hit: 1.0, output: 50.0, limitedAvailability: true },
91
+ // Claude 5 generation (launched 2026-06-09)
92
+ [AnthropicModels.Fable5]: { input: 10.0, cache_write: 12.5, cache_hit: 1.0, output: 50.0 },
93
+ [AnthropicModels.Sonnet5]: { input: 3.0, cache_write: 3.75, cache_hit: 0.3, output: 15.0 },
94
+ [AnthropicModels.Mythos5]: { input: 10.0, cache_write: 12.5, cache_hit: 1.0, output: 50.0, limitedAvailability: true },
95
+ [AnthropicModels.MythosPreview]: { input: 10.0, cache_write: 12.5, cache_hit: 1.0, output: 50.0, limitedAvailability: true },
83
96
  [AnthropicModels.Opus4_7]: { input: 5.0, cache_write: 6.25, cache_hit: 0.5, output: 25.0 },
84
97
  [AnthropicModels.Opus4_6]: { input: 5.0, cache_write: 6.25, cache_hit: 0.5, output: 25.0 },
85
98
  [AnthropicModels.Opus4_6Fast]: { input: 30.0, cache_write: 37.5, cache_hit: 3.0, output: 150.0, limitedAvailability: true },
@@ -1,8 +1,10 @@
1
+ import { ModelPricing } from "./types";
2
+
1
3
  /**
2
4
  * Fireworks AI pricing (USD per 1M tokens)
3
5
  * Source: https://fireworks.ai/pricing
4
6
  */
5
- export const FireworksTextPricing: Record<string, { input: number; output: number; cache_hit?: number }> = {
7
+ export const FireworksTextPricing: Record<string, ModelPricing> = {
6
8
  // Moonshot AI
7
9
  "accounts/fireworks/models/kimi-k2p7-code": { input: 0.95, cache_hit: 0.19, output: 4.0 },
8
10
  "accounts/fireworks/models/kimi-k2-6": { input: 0.95, cache_hit: 0.16, output: 4.0 },
@@ -14,22 +16,26 @@ export const FireworksTextPricing: Record<string, { input: number; output: numbe
14
16
  "accounts/fireworks/models/minimax-m2-5": { input: 0.30, cache_hit: 0.03, output: 1.20 },
15
17
 
16
18
  // Qwen
17
- "accounts/fireworks/models/qwen3-6-plus": { input: 0.50, cache_hit: 0.10, output: 3.0 },
18
- "accounts/fireworks/models/qwen3p6-plus": { input: 0.50, cache_hit: 0.10, output: 3.0 },
19
- "accounts/fireworks/models/qwen3-vl-30b-a3b-thinking": { input: 0.15, cache_hit: 0.08, output: 0.60 },
20
- "accounts/fireworks/models/qwen3-vl-30b-a3b-instruct": { input: 0.15, cache_hit: 0.08, output: 0.60 },
21
- "accounts/fireworks/models/qwen3-8b": { input: 0.20, cache_hit: 0.10, output: 0.20 },
19
+ "accounts/fireworks/models/qwen3p7-plus": { input: 0.40, cache_hit: 0.08, output: 1.60 },
20
+
21
+ // Deprecated QWEN Models
22
+ "accounts/fireworks/models/qwen3-6-plus": { input: 0.50, cache_hit: 0.10, output: 3.0, deprecated: true},
23
+ "accounts/fireworks/models/qwen3p6-plus": { input: 0.50, cache_hit: 0.10, output: 3.0, deprecated: true},
24
+ "accounts/fireworks/models/qwen3-vl-30b-a3b-thinking": { input: 0.15, cache_hit: 0.08, output: 0.60, deprecated: true},
25
+ "accounts/fireworks/models/qwen3-vl-30b-a3b-instruct": { input: 0.15, cache_hit: 0.08, output: 0.60, deprecated: true},
26
+ "accounts/fireworks/models/qwen3-8b": { input: 0.20, cache_hit: 0.10, output: 0.20, deprecated: true},
22
27
 
23
28
  // Z.ai
24
29
  "accounts/fireworks/models/glm-5p2": { input: 1.40, cache_hit: 0.26, output: 4.40 },
25
- "accounts/fireworks/models/glm-5-2": { input: 1.40, cache_hit: 0.26, output: 4.40 },
26
- "accounts/fireworks/models/glm-5-1": { input: 1.40, cache_hit: 0.26, output: 4.40 },
27
- "accounts/fireworks/models/glm-5": { input: 1.00, cache_hit: 0.20, output: 3.20 },
28
- "accounts/fireworks/models/glm-4-7": { input: 0.60, cache_hit: 0.30, output: 2.20 },
30
+ "accounts/fireworks/models/glm-5p1": { input: 1.40, cache_hit: 0.26, output: 4.40 },
31
+ "accounts/fireworks/models/glm-5": { input: 1.00, cache_hit: 0.20, output: 3.20, deprecated: true },
32
+ "accounts/fireworks/models/glm-4-7": { input: 0.60, cache_hit: 0.30, output: 2.20, deprecated: true},
29
33
 
30
34
  // DeepSeek AI
31
- "accounts/fireworks/models/deepseek-v3-2": { input: 0.56, cache_hit: 0.28, output: 1.68 },
32
- "accounts/fireworks/models/deepseek-v3-1": { input: 0.56, cache_hit: 0.28, output: 1.68 },
35
+ "accounts/fireworks/models/deepseek-v4-pro": { input: 1.74, cache_hit: 0.15, output: 3.48 },
36
+ "accounts/fireworks/models/deepseek-v4-flash": { input: 0.14, cache_hit: 0.03, output: 0.28 },
37
+ "accounts/fireworks/models/deepseek-v3-2": { input: 0.56, cache_hit: 0.28, output: 1.68, deprecated: true },
38
+ "accounts/fireworks/models/deepseek-v3-1": { input: 0.56, cache_hit: 0.28, output: 1.68, deprecated: true },
33
39
 
34
40
  // OpenAI OSS
35
41
  "accounts/fireworks/models/gpt-oss-120b": { input: 0.15, cache_hit: 0.01, output: 0.60 },
@@ -36,6 +36,7 @@ export { OpenRouterTextPricing } from "./openrouter";
36
36
  export { LlamaTextPricing } from "./llama";
37
37
  export { CopilotTextPricing, CopilotModelMultipliers } from "./copilot";
38
38
  export { FireworksTextPricing } from "./fireworks";
39
+ export { MetaTextPricing, MetaWebSearchPricingPer1000Queries } from "./meta";
39
40
 
40
41
  // ─── Combined catalog ─────────────────────────────────────────────────────────
41
42
  export { ALL_MODEL_CATALOG, USAGE_MARKUP_PERCENT } from "./models";
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Meta Model API pricing (USD per 1M tokens)
3
+ * Source: Meta Model API docs — https://api.meta.ai
4
+ * New accounts start with $20 in free credits.
5
+ */
6
+ export const MetaTextPricing: Record<string, { input: number; output: number; cached_input?: number }> = {
7
+ "muse-spark-1.1": { input: 1.25, output: 4.25, cached_input: 0.15 },
8
+ };
9
+
10
+ // Web search grounding is billed per 1,000 search queries ($2.50/1,000),
11
+ // not per-token, so it isn't represented in the per-token pricing map above.
12
+ export const MetaWebSearchPricingPer1000Queries = 2.5;
@@ -16,6 +16,9 @@ import {
16
16
  // ─── Model IDs ────────────────────────────────────────────────────────────────
17
17
 
18
18
  export const OpenAiModels = {
19
+ GPT_56_Sol: "gpt-5.6-sol",
20
+ GPT_56_Terra: "gpt-5.6-terra",
21
+ GPT_56_Luna: "gpt-5.6-luna",
19
22
  GPT_55: "gpt-5.5",
20
23
  GPT_55_Pro: "gpt-5.5-pro",
21
24
  GPT_54: "gpt-5.4",
@@ -95,6 +98,9 @@ export const OpenAiEmbeddingModels: Record<string, string> = {
95
98
 
96
99
  export const OpenAiReasoningModels: string[] = [
97
100
  OpenAiModels.GPT_5,
101
+ OpenAiModels.GPT_56_Sol,
102
+ OpenAiModels.GPT_56_Terra,
103
+ OpenAiModels.GPT_56_Luna,
98
104
  OpenAiModels.GPT_5_Pro,
99
105
  OpenAiModels.GPT_5_Mini,
100
106
  OpenAiModels.GPT_5_Nano,
@@ -125,6 +131,9 @@ export const OpenAiChatModels: string[] = [
125
131
  OpenAiModels.GPT_41,
126
132
  OpenAiModels.GPT_41_Mini,
127
133
  OpenAiModels.GPT_41_Nano,
134
+ OpenAiModels.GPT_56_Sol,
135
+ OpenAiModels.GPT_56_Terra,
136
+ OpenAiModels.GPT_56_Luna,
128
137
  OpenAiModels.GPT_54,
129
138
  OpenAiModels.GPT_54_Mini,
130
139
  OpenAiModels.GPT_55,
@@ -218,6 +227,10 @@ export const OpenAiSearchModels: string[] = [
218
227
  // ─── Pricing (USD per 1M tokens) ──────────────────────────────────────────────
219
228
 
220
229
  export const OpenAiTextPricing: Record<string, ModelPricing> = {
230
+ // gpt-5.6 series — short context / long context pricing
231
+ [OpenAiModels.GPT_56_Sol]: { input: 5.0, cached_input: 0.5, cache_write: 6.25, output: 30.0, input_gt_200k: 10.0, output_gt_200k: 45.0 },
232
+ [OpenAiModels.GPT_56_Terra]: { input: 2.5, cached_input: 0.25, cache_write: 3.125, output: 15.0, input_gt_200k: 5.0, output_gt_200k: 22.5 },
233
+ [OpenAiModels.GPT_56_Luna]: { input: 1.0, cached_input: 0.10, cache_write: 1.25, output: 6.0, input_gt_200k: 2.0, output_gt_200k: 9.0 },
221
234
  [OpenAiModels.GPT_55]: { input: 5.0, cached_input: 0.5, output: 30.0 },
222
235
  [OpenAiModels.GPT_55_Pro]: { input: 30.0, cached_input: 0, output: 180.0, reasoningLevels: ["medium", "high", "xhigh"] },
223
236
  [OpenAiModels.GPT_54]: { input: 2.5, cached_input: 0.25, output: 15.0 },
@@ -10,6 +10,7 @@ export const XaiModels = {
10
10
  Grok_4_20_Reasoning: "grok-4.20-0309-reasoning",
11
11
  Grok_4_20_NonReasoning: "grok-4.20-0309-non-reasoning",
12
12
  Grok_4_20_MultiAgent: "grok-4.20-multi-agent-0309",
13
+ Grok4_5: "grok-4.5",
13
14
  Grok4_1_Fast_Reasoning: "grok-4-1-fast-reasoning",
14
15
  Grok4_1_Fast_NonReasoning: "grok-4-1-fast-non-reasoning",
15
16
  GrokCodeFast: "grok-code-fast-1",
@@ -44,6 +45,7 @@ export const XaiTextModels: string[] = [
44
45
  XaiModels.Grok_4_20_Reasoning, XaiModels.Grok_4_20_NonReasoning,
45
46
  XaiModels.Grok_4_20_MultiAgent,
46
47
  XaiModels.Grok4_1_Fast_Reasoning, XaiModels.Grok4_1_Fast_NonReasoning,
48
+ XaiModels.Grok4_5,
47
49
  XaiModels.GrokCodeFast, XaiModels.Grok4,
48
50
  XaiModels.Grok3Beta, XaiModels.Grok3MiniBeta, XaiModels.Grok3FastBeta, XaiModels.Grok3MiniFastBeta,
49
51
  ];
@@ -87,6 +89,7 @@ export const XaiTextPricing: Record<string, ModelPricing> = {
87
89
  [XaiModels.Grok_4_20_MultiAgent]: { input: 2.0, cache_hit: 0.20, output: 6.0, reasoningLevels: ["low", "medium", "high", "xhigh"], useResponsesApi: true },
88
90
  [XaiModels.Grok4_1_Fast_Reasoning]: { input: 0.2, cache_hit: 0.05, output: 0.5, useResponsesApi: true },
89
91
  [XaiModels.Grok4_1_Fast_NonReasoning]: { input: 0.2, cache_hit: 0.05, output: 0.5, useResponsesApi: true },
92
+ [XaiModels.Grok4_5]: { input: 2.0, cache_hit: 0.50, output: 6.0 },
90
93
  [XaiModels.GrokCodeFast]: { input: 0.2, cache_hit: 0.02, output: 1.5 },
91
94
  [XaiModels.Grok4]: { input: 3.0, output: 15.0 },
92
95
  [XaiModels.Grok3Beta]: { input: 3.0, output: 15.0 },
@@ -1,6 +1,6 @@
1
1
  import { includedTools } from "../agents/tools/list";
2
2
  import * as allTools from "../agents/tools";
3
- import { LazyToolsService, services } from "../services";
3
+ import { LazyToolsService, services, MinimalToolsService } from "../services";
4
4
  import { agents } from "../agents";
5
5
  import { ModulesService } from "../services/modules";
6
6