@tyvm/knowhow 0.0.130 → 0.0.132

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 (97) hide show
  1. package/package.json +1 -1
  2. package/src/agents/configurable/ConfigAgent.ts +0 -1
  3. package/src/agents/tools/startAgentTask.ts +17 -13
  4. package/src/ai.ts +55 -24
  5. package/src/chat/CliChatService.ts +7 -1
  6. package/src/chat/modules/AgentModule.ts +72 -14
  7. package/src/chat/renderer/PlainRenderer.ts +218 -0
  8. package/src/chat/renderer/index.ts +1 -0
  9. package/src/chat/renderer/loadRenderer.ts +2 -0
  10. package/src/chat.ts +2 -2
  11. package/src/cli.ts +23 -0
  12. package/src/clients/anthropic.ts +9 -1
  13. package/src/clients/fireworks.ts +10 -1
  14. package/src/clients/index.ts +6 -3
  15. package/src/clients/meta.ts +9 -0
  16. package/src/clients/pricing/anthropic.ts +11 -0
  17. package/src/clients/pricing/fireworks.ts +12 -0
  18. package/src/commands/agent.ts +53 -20
  19. package/src/commands/agents.ts +556 -0
  20. package/src/commands/hash.ts +170 -0
  21. package/src/commands/misc.ts +157 -3
  22. package/src/commands/skills.ts +36 -0
  23. package/src/config.ts +54 -2
  24. package/src/generate.ts +507 -0
  25. package/src/index.ts +32 -216
  26. package/src/services/BehaviorsService.ts +32 -0
  27. package/src/services/SkillsService.ts +198 -0
  28. package/src/types.ts +36 -4
  29. package/ts_build/package.json +1 -1
  30. package/ts_build/src/agents/configurable/ConfigAgent.js.map +1 -1
  31. package/ts_build/src/agents/tools/startAgentTask.d.ts +2 -2
  32. package/ts_build/src/agents/tools/startAgentTask.js +13 -12
  33. package/ts_build/src/agents/tools/startAgentTask.js.map +1 -1
  34. package/ts_build/src/ai.d.ts +10 -4
  35. package/ts_build/src/ai.js +27 -25
  36. package/ts_build/src/ai.js.map +1 -1
  37. package/ts_build/src/chat/CliChatService.d.ts +1 -1
  38. package/ts_build/src/chat/CliChatService.js +4 -1
  39. package/ts_build/src/chat/CliChatService.js.map +1 -1
  40. package/ts_build/src/chat/modules/AgentModule.js +61 -4
  41. package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
  42. package/ts_build/src/chat/renderer/PlainRenderer.d.ts +28 -0
  43. package/ts_build/src/chat/renderer/PlainRenderer.js +169 -0
  44. package/ts_build/src/chat/renderer/PlainRenderer.js.map +1 -0
  45. package/ts_build/src/chat/renderer/index.d.ts +1 -0
  46. package/ts_build/src/chat/renderer/index.js +3 -1
  47. package/ts_build/src/chat/renderer/index.js.map +1 -1
  48. package/ts_build/src/chat/renderer/loadRenderer.js +2 -0
  49. package/ts_build/src/chat/renderer/loadRenderer.js.map +1 -1
  50. package/ts_build/src/chat.d.ts +1 -1
  51. package/ts_build/src/chat.js +2 -2
  52. package/ts_build/src/chat.js.map +1 -1
  53. package/ts_build/src/cli.js +16 -0
  54. package/ts_build/src/cli.js.map +1 -1
  55. package/ts_build/src/clients/anthropic.js +4 -1
  56. package/ts_build/src/clients/anthropic.js.map +1 -1
  57. package/ts_build/src/clients/fireworks.js +7 -0
  58. package/ts_build/src/clients/fireworks.js.map +1 -1
  59. package/ts_build/src/clients/index.js +5 -1
  60. package/ts_build/src/clients/index.js.map +1 -1
  61. package/ts_build/src/clients/meta.d.ts +2 -0
  62. package/ts_build/src/clients/meta.js +5 -0
  63. package/ts_build/src/clients/meta.js.map +1 -1
  64. package/ts_build/src/clients/pricing/anthropic.d.ts +3 -0
  65. package/ts_build/src/clients/pricing/anthropic.js +6 -0
  66. package/ts_build/src/clients/pricing/anthropic.js.map +1 -1
  67. package/ts_build/src/clients/pricing/fireworks.d.ts +1 -0
  68. package/ts_build/src/clients/pricing/fireworks.js +5 -1
  69. package/ts_build/src/clients/pricing/fireworks.js.map +1 -1
  70. package/ts_build/src/commands/agent.js +44 -17
  71. package/ts_build/src/commands/agent.js.map +1 -1
  72. package/ts_build/src/commands/agents.d.ts +2 -0
  73. package/ts_build/src/commands/agents.js +460 -0
  74. package/ts_build/src/commands/agents.js.map +1 -0
  75. package/ts_build/src/commands/hash.d.ts +2 -0
  76. package/ts_build/src/commands/hash.js +150 -0
  77. package/ts_build/src/commands/hash.js.map +1 -0
  78. package/ts_build/src/commands/misc.js +108 -2
  79. package/ts_build/src/commands/misc.js.map +1 -1
  80. package/ts_build/src/commands/skills.js +24 -0
  81. package/ts_build/src/commands/skills.js.map +1 -1
  82. package/ts_build/src/config.js +37 -1
  83. package/ts_build/src/config.js.map +1 -1
  84. package/ts_build/src/generate.d.ts +16 -0
  85. package/ts_build/src/generate.js +304 -0
  86. package/ts_build/src/generate.js.map +1 -0
  87. package/ts_build/src/index.d.ts +1 -3
  88. package/ts_build/src/index.js +9 -118
  89. package/ts_build/src/index.js.map +1 -1
  90. package/ts_build/src/services/BehaviorsService.d.ts +2 -0
  91. package/ts_build/src/services/BehaviorsService.js +24 -0
  92. package/ts_build/src/services/BehaviorsService.js.map +1 -1
  93. package/ts_build/src/services/SkillsService.d.ts +7 -0
  94. package/ts_build/src/services/SkillsService.js +163 -0
  95. package/ts_build/src/services/SkillsService.js.map +1 -1
  96. package/ts_build/src/types.d.ts +14 -4
  97. package/ts_build/src/types.js.map +1 -1
@@ -519,7 +519,15 @@ export class GenericAnthropicClient implements GenericClient {
519
519
  const rawP = this.pricesPerMillion()[model];
520
520
  // Fall back to pricing file for unknown/newer models
521
521
  const fallback = AnthropicTextPricing[model as keyof typeof AnthropicTextPricing];
522
- const p: any = rawP || fallback || undefined;
522
+ // Second fallback: short aliases like "claude-sonnet-4-5" don't have their
523
+ // own entry but map to a dated version like "claude-sonnet-4-5-20250929".
524
+ // Find the first pricing entry whose key starts with the short model name.
525
+ const aliasFallback = !rawP && !fallback
526
+ ? Object.entries(AnthropicTextPricing).find(([key]) =>
527
+ key.startsWith(model + "-")
528
+ )?.[1]
529
+ : undefined;
530
+ const p: any = rawP || fallback || aliasFallback || undefined;
523
531
  if (!p) return undefined;
524
532
 
525
533
  const inputTokens = usage.input_tokens ?? 0;
@@ -1,5 +1,5 @@
1
1
  import { HttpClient } from "./http";
2
- import { FireworksTextPricing } from "./pricing/fireworks";
2
+ import { FireworksTextPricing, FireworksEmbeddingPricing } from "./pricing/fireworks";
3
3
  import { CompletionOptions, CompletionResponse } from "./types";
4
4
 
5
5
  type ModelInfo = { id: string; object: string; owned_by: string };
@@ -22,6 +22,15 @@ export class GenericFireworksClient extends HttpClient {
22
22
  * Our pricing map is the authoritative source of truth for available models.
23
23
  */
24
24
  async getModels(_type = "all"): Promise<ModelInfo[]> {
25
+ // Return embedding/reranker models when requested
26
+ if (_type === "embedding") {
27
+ return Object.keys(FireworksEmbeddingPricing).map((id) => ({
28
+ id,
29
+ object: "model",
30
+ owned_by: "fireworks",
31
+ }));
32
+ }
33
+
25
34
  return Object.keys(FireworksTextPricing).map((id) => ({
26
35
  id,
27
36
  object: "model",
@@ -310,9 +310,12 @@ export class AIClient {
310
310
 
311
311
  if (!client) {
312
312
  if (entry.provider === "knowhow") {
313
- console.warn(
314
- `⚠️ Knowhow provider is not logged in. Run 'knowhow login' to enable Knowhow models.`
315
- );
313
+ if (process.env.KNOWHOW_CLI) {
314
+ const warnNeeds = (process.env.KNOWHOW_WARN_NEEDS ?? "").split(",");
315
+ if (warnNeeds.includes("models")) console.warn(
316
+ `⚠️ Knowhow provider is not logged in. Run 'knowhow login' to enable Knowhow models.`
317
+ );
318
+ }
316
319
  }
317
320
  continue;
318
321
  }
@@ -1,5 +1,6 @@
1
1
  import { HttpClient } from "./http";
2
2
  import { MetaTextPricing } from "./pricing/meta";
3
+ import { ModelModality } from "./types";
3
4
 
4
5
  /**
5
6
  * Meta Model API client — OpenAI-compatible API
@@ -15,4 +16,12 @@ export class GenericMetaClient extends HttpClient {
15
16
  if (apiKey) this.setJwt(apiKey);
16
17
  this.setPrices(MetaTextPricing);
17
18
  }
19
+
20
+ /**
21
+ * Meta Model API only provides chat completion models — no embeddings, images, audio, or video.
22
+ */
23
+ async getModels(type: ModelModality | "all" = "all") {
24
+ if (type === "embedding") return [];
25
+ return super.getModels(type as string);
26
+ }
18
27
  }
@@ -10,6 +10,13 @@ import { completions, ModelCatalogEntry, ModelPricing } from "./types";
10
10
  export const AnthropicModels = {
11
11
  // Active models
12
12
  Fable5: "claude-fable-5",
13
+ // Short aliases (without date suffix) — Anthropic resolves these to the latest
14
+ // dated version. Pricing entries for the short aliases are added to the pricing
15
+ // table below so cost tracking works regardless of whether the user specifies
16
+ // the full dated name or the short alias.
17
+ Sonnet4_5Short: "claude-sonnet-4-5",
18
+ Haiku4_5Short: "claude-haiku-4-5",
19
+ Opus4_5Short: "claude-opus-4-5",
13
20
  Sonnet5: "claude-sonnet-5",
14
21
  Mythos5: "claude-mythos-5",
15
22
  MythosPreview: "claude-mythos-preview",
@@ -101,6 +108,10 @@ export const AnthropicTextPricing: Record<string, ModelPricing> = {
101
108
  [AnthropicModels.Opus4_1]: { input: 15.0, cache_write: 18.75, cache_hit: 1.5, output: 75.0 },
102
109
  [AnthropicModels.Sonnet4_5]: { input: 3.0, input_gt_200k: 6.0, cache_write: 3.75, cache_hit: 0.3, output: 15.0, output_gt_200k: 22.5 },
103
110
  [AnthropicModels.Haiku4_5]: { input: 1.0, cache_write: 1.25, cache_hit: 0.1, output: 5.0 },
111
+ // Short aliases — same pricing as their dated counterparts
112
+ [AnthropicModels.Sonnet4_5Short]: { input: 3.0, input_gt_200k: 6.0, cache_write: 3.75, cache_hit: 0.3, output: 15.0, output_gt_200k: 22.5 },
113
+ [AnthropicModels.Haiku4_5Short]: { input: 1.0, cache_write: 1.25, cache_hit: 0.1, output: 5.0 },
114
+ [AnthropicModels.Opus4_5Short]: { input: 5.0, cache_write: 6.25, cache_hit: 0.5, output: 25.0 },
104
115
  // Deprecated — pricing retained for cost tracking
105
116
  [AnthropicModels.Opus4]: { input: 15.0, cache_write: 18.75, cache_hit: 1.5, output: 75.0, deprecated: true, deprecationDate: "2026-06-15" },
106
117
  [AnthropicModels.Sonnet4]: { input: 3.0, input_gt_200k: 6.0, cache_write: 3.75, cache_hit: 0.3, output: 15.0, output_gt_200k: 22.5, deprecated: true, deprecationDate: "2026-06-15" },
@@ -40,3 +40,15 @@ export const FireworksTextPricing: Record<string, ModelPricing> = {
40
40
  // OpenAI OSS
41
41
  "accounts/fireworks/models/gpt-oss-120b": { input: 0.15, cache_hit: 0.01, output: 0.60 },
42
42
  };
43
+
44
+ /**
45
+ * Fireworks AI embedding/reranker model pricing (USD per 1M tokens)
46
+ * Source: https://fireworks.ai/pricing
47
+ */
48
+ export const FireworksEmbeddingPricing: Record<string, ModelPricing> = {
49
+ // Qwen3 Embedding 8B — $0.10/M tokens, context 40k
50
+ "accounts/fireworks/models/qwen3-embedding-8b": { input: 0.10, output: 0.10 },
51
+
52
+ // Qwen3 Reranker 8B — $0.20/M tokens, context 40k
53
+ "accounts/fireworks/models/qwen3-reranker-8b": { input: 0.20, output: 0.20 },
54
+ };
@@ -1,14 +1,31 @@
1
1
  import { Command } from "commander";
2
2
  import { readPromptFile } from "../ai";
3
+ import { BehaviorsService } from "../services/BehaviorsService";
3
4
  import { AgentModule } from "../chat/modules/AgentModule";
4
- import { BehaviorsService, Behavior } from "../services/BehaviorsService";
5
5
  import { AskModule } from "../chat/modules/AskModule";
6
6
  import { SearchModule } from "../chat/modules/SearchModule";
7
7
  import { SessionsModule } from "../chat/modules/SessionsModule";
8
8
  import { SetupModule } from "../chat/modules/SetupModule";
9
+ import { PlainRenderer } from "../chat/renderer/PlainRenderer";
9
10
  import { loadRenderer } from "../chat/renderer/loadRenderer";
10
11
  import { getConfig } from "../config";
11
12
 
13
+ async function setupRenderer(chatService: any, rendererSpecifier: string): Promise<void> {
14
+ const resolved =
15
+ rendererSpecifier === "basic" && !process.stdout.isTTY ? "plain" : rendererSpecifier;
16
+ try {
17
+ const renderer = await loadRenderer(resolved);
18
+ chatService.setContext({ renderer });
19
+ } catch (err: any) {
20
+ console.warn(`⚠ Could not load renderer "${resolved}": ${err.message}`);
21
+ console.warn(" Falling back to basic renderer.");
22
+ try {
23
+ const fallback = !process.stdout.isTTY ? new PlainRenderer() : await loadRenderer("basic");
24
+ chatService.setContext({ renderer: fallback });
25
+ } catch (_) {}
26
+ }
27
+ }
28
+
12
29
  async function readStdin(): Promise<string> {
13
30
  return new Promise((resolve) => {
14
31
  let data = "";
@@ -28,24 +45,6 @@ async function readStdin(): Promise<string> {
28
45
  });
29
46
  }
30
47
 
31
- /**
32
- * Set up the renderer on the chat service context.
33
- * Priority: CLI --renderer flag > config.chat.renderer > "basic" (ConsoleRenderer)
34
- */
35
- async function setupRenderer(chatService: any, rendererSpecifier: string): Promise<void> {
36
- try {
37
- const renderer = await loadRenderer(rendererSpecifier);
38
- chatService.setContext({ renderer });
39
- } catch (err: any) {
40
- console.warn(`⚠ Could not load renderer "${rendererSpecifier}": ${err.message}`);
41
- console.warn(" Falling back to basic renderer.");
42
- try {
43
- const fallback = await loadRenderer("basic");
44
- chatService.setContext({ renderer: fallback });
45
- } catch (_) {}
46
- }
47
- }
48
-
49
48
  export function addAgentCommand(program: Command, getChatService: () => any): void {
50
49
  program
51
50
  .command("agent")
@@ -68,6 +67,14 @@ export function addAgentCommand(program: Command, getChatService: () => any): vo
68
67
  )
69
68
  .option("--message-id <messageId>", "Knowhow message ID for task tracking")
70
69
  .option("--sync-fs", "Enable filesystem-based synchronization")
70
+ .option(
71
+ "--behavior-id <id>",
72
+ "Force a specific behavior by its ID (skips trigger matching)"
73
+ )
74
+ .option(
75
+ "--behavior-file <path>",
76
+ "Force a specific behavior by its file path (skips trigger matching)"
77
+ )
71
78
  .option(
72
79
  "--task-id <taskId>",
73
80
  "Pre-generated task ID (used with --sync-fs for predictable agent directory path)"
@@ -93,6 +100,7 @@ export function addAgentCommand(program: Command, getChatService: () => any): vo
93
100
  try { config = await getConfig(); } catch (_) {}
94
101
  const rendererSpecifier = options.renderer ?? config.chat?.renderer ?? "basic";
95
102
  await setupRenderer(chatService, rendererSpecifier);
103
+
96
104
  const agentModule = new AgentModule();
97
105
 
98
106
  if (options.resume) {
@@ -137,7 +145,32 @@ export function addAgentCommand(program: Command, getChatService: () => any): vo
137
145
  let behaviorSystemPrompt: string | undefined;
138
146
  let behaviorModel: string | undefined;
139
147
  const behaviorsSvc = new BehaviorsService();
140
- const matchedBehavior = behaviorsSvc.matchBehaviorLocal(input);
148
+
149
+ let matchedBehavior = null;
150
+
151
+ if (options.behaviorFile) {
152
+ // Load behavior directly from a file path
153
+ matchedBehavior = behaviorsSvc.loadBehaviorFromFile(options.behaviorFile);
154
+ if (matchedBehavior) {
155
+ console.log(`🎯 Using behavior from file: ${options.behaviorFile}`);
156
+ } else {
157
+ console.error(`❌ Could not load behavior from file: ${options.behaviorFile}`);
158
+ process.exit(1);
159
+ }
160
+ } else if (options.behaviorId) {
161
+ // Load behavior by ID (searches local disk behaviors)
162
+ matchedBehavior = behaviorsSvc.findBehaviorById(options.behaviorId);
163
+ if (matchedBehavior) {
164
+ console.log(`🎯 Using behavior by ID: ${options.behaviorId} (${matchedBehavior.name})`);
165
+ } else {
166
+ console.error(`❌ No behavior found with ID: ${options.behaviorId}`);
167
+ process.exit(1);
168
+ }
169
+ } else {
170
+ // Default: match by trigger text
171
+ matchedBehavior = behaviorsSvc.matchBehaviorLocal(input);
172
+ }
173
+
141
174
  if (matchedBehavior) {
142
175
  console.log(`🎯 Matched behavior: ${matchedBehavior.name}`);
143
176
  if (matchedBehavior.instructions) {