@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.
- package/package.json +1 -1
- package/src/agents/configurable/ConfigAgent.ts +0 -1
- package/src/agents/tools/startAgentTask.ts +17 -13
- package/src/ai.ts +55 -24
- package/src/chat/CliChatService.ts +7 -1
- package/src/chat/modules/AgentModule.ts +72 -14
- package/src/chat/renderer/PlainRenderer.ts +218 -0
- package/src/chat/renderer/index.ts +1 -0
- package/src/chat/renderer/loadRenderer.ts +2 -0
- package/src/chat.ts +2 -2
- package/src/cli.ts +23 -0
- package/src/clients/anthropic.ts +9 -1
- package/src/clients/fireworks.ts +10 -1
- package/src/clients/index.ts +6 -3
- package/src/clients/meta.ts +9 -0
- package/src/clients/pricing/anthropic.ts +11 -0
- package/src/clients/pricing/fireworks.ts +12 -0
- package/src/commands/agent.ts +53 -20
- package/src/commands/agents.ts +556 -0
- package/src/commands/hash.ts +170 -0
- package/src/commands/misc.ts +157 -3
- package/src/commands/skills.ts +36 -0
- package/src/config.ts +54 -2
- package/src/generate.ts +507 -0
- package/src/index.ts +32 -216
- package/src/services/BehaviorsService.ts +32 -0
- package/src/services/SkillsService.ts +198 -0
- package/src/types.ts +36 -4
- package/ts_build/package.json +1 -1
- package/ts_build/src/agents/configurable/ConfigAgent.js.map +1 -1
- package/ts_build/src/agents/tools/startAgentTask.d.ts +2 -2
- package/ts_build/src/agents/tools/startAgentTask.js +13 -12
- package/ts_build/src/agents/tools/startAgentTask.js.map +1 -1
- package/ts_build/src/ai.d.ts +10 -4
- package/ts_build/src/ai.js +27 -25
- package/ts_build/src/ai.js.map +1 -1
- package/ts_build/src/chat/CliChatService.d.ts +1 -1
- package/ts_build/src/chat/CliChatService.js +4 -1
- package/ts_build/src/chat/CliChatService.js.map +1 -1
- package/ts_build/src/chat/modules/AgentModule.js +61 -4
- package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
- package/ts_build/src/chat/renderer/PlainRenderer.d.ts +28 -0
- package/ts_build/src/chat/renderer/PlainRenderer.js +169 -0
- package/ts_build/src/chat/renderer/PlainRenderer.js.map +1 -0
- package/ts_build/src/chat/renderer/index.d.ts +1 -0
- package/ts_build/src/chat/renderer/index.js +3 -1
- package/ts_build/src/chat/renderer/index.js.map +1 -1
- package/ts_build/src/chat/renderer/loadRenderer.js +2 -0
- package/ts_build/src/chat/renderer/loadRenderer.js.map +1 -1
- package/ts_build/src/chat.d.ts +1 -1
- package/ts_build/src/chat.js +2 -2
- package/ts_build/src/chat.js.map +1 -1
- package/ts_build/src/cli.js +16 -0
- package/ts_build/src/cli.js.map +1 -1
- package/ts_build/src/clients/anthropic.js +4 -1
- package/ts_build/src/clients/anthropic.js.map +1 -1
- package/ts_build/src/clients/fireworks.js +7 -0
- package/ts_build/src/clients/fireworks.js.map +1 -1
- package/ts_build/src/clients/index.js +5 -1
- package/ts_build/src/clients/index.js.map +1 -1
- package/ts_build/src/clients/meta.d.ts +2 -0
- package/ts_build/src/clients/meta.js +5 -0
- package/ts_build/src/clients/meta.js.map +1 -1
- package/ts_build/src/clients/pricing/anthropic.d.ts +3 -0
- package/ts_build/src/clients/pricing/anthropic.js +6 -0
- package/ts_build/src/clients/pricing/anthropic.js.map +1 -1
- package/ts_build/src/clients/pricing/fireworks.d.ts +1 -0
- package/ts_build/src/clients/pricing/fireworks.js +5 -1
- package/ts_build/src/clients/pricing/fireworks.js.map +1 -1
- package/ts_build/src/commands/agent.js +44 -17
- package/ts_build/src/commands/agent.js.map +1 -1
- package/ts_build/src/commands/agents.d.ts +2 -0
- package/ts_build/src/commands/agents.js +460 -0
- package/ts_build/src/commands/agents.js.map +1 -0
- package/ts_build/src/commands/hash.d.ts +2 -0
- package/ts_build/src/commands/hash.js +150 -0
- package/ts_build/src/commands/hash.js.map +1 -0
- package/ts_build/src/commands/misc.js +108 -2
- package/ts_build/src/commands/misc.js.map +1 -1
- package/ts_build/src/commands/skills.js +24 -0
- package/ts_build/src/commands/skills.js.map +1 -1
- package/ts_build/src/config.js +37 -1
- package/ts_build/src/config.js.map +1 -1
- package/ts_build/src/generate.d.ts +16 -0
- package/ts_build/src/generate.js +304 -0
- package/ts_build/src/generate.js.map +1 -0
- package/ts_build/src/index.d.ts +1 -3
- package/ts_build/src/index.js +9 -118
- package/ts_build/src/index.js.map +1 -1
- package/ts_build/src/services/BehaviorsService.d.ts +2 -0
- package/ts_build/src/services/BehaviorsService.js +24 -0
- package/ts_build/src/services/BehaviorsService.js.map +1 -1
- package/ts_build/src/services/SkillsService.d.ts +7 -0
- package/ts_build/src/services/SkillsService.js +163 -0
- package/ts_build/src/services/SkillsService.js.map +1 -1
- package/ts_build/src/types.d.ts +14 -4
- package/ts_build/src/types.js.map +1 -1
package/src/clients/anthropic.ts
CHANGED
|
@@ -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
|
-
|
|
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;
|
package/src/clients/fireworks.ts
CHANGED
|
@@ -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",
|
package/src/clients/index.ts
CHANGED
|
@@ -310,9 +310,12 @@ export class AIClient {
|
|
|
310
310
|
|
|
311
311
|
if (!client) {
|
|
312
312
|
if (entry.provider === "knowhow") {
|
|
313
|
-
|
|
314
|
-
|
|
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
|
}
|
package/src/clients/meta.ts
CHANGED
|
@@ -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
|
+
};
|
package/src/commands/agent.ts
CHANGED
|
@@ -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
|
-
|
|
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) {
|