kavoru 0.9.3 → 0.9.5
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/args.ts +1 -1
- package/src/features.ts +73 -2
package/package.json
CHANGED
package/src/args.ts
CHANGED
|
@@ -37,7 +37,7 @@ Options:
|
|
|
37
37
|
--no-features <list> Comma-separated features to exclude
|
|
38
38
|
|
|
39
39
|
Features:
|
|
40
|
-
auth, postgres, otel, sentry, kafka, redis, websocket, resend, cron, cli
|
|
40
|
+
auth, postgres, otel, sentry, kafka, redis, llama, websocket, resend, cron, cli
|
|
41
41
|
(prisma is accepted as an alias for postgres; kavoru-cli for cli)
|
|
42
42
|
Docker Compose is always included — not a toggle.
|
|
43
43
|
|
package/src/features.ts
CHANGED
|
@@ -9,6 +9,7 @@ export type FeatureId =
|
|
|
9
9
|
| "sentry"
|
|
10
10
|
| "kafka"
|
|
11
11
|
| "redis"
|
|
12
|
+
| "llama"
|
|
12
13
|
| "websocket"
|
|
13
14
|
| "resend"
|
|
14
15
|
| "cron"
|
|
@@ -61,6 +62,11 @@ export const FEATURES: FeatureDef[] = [
|
|
|
61
62
|
label: "Redis",
|
|
62
63
|
description: "Cache client and CRUD HTTP endpoints",
|
|
63
64
|
},
|
|
65
|
+
{
|
|
66
|
+
id: "llama",
|
|
67
|
+
label: "Llama (Ollama)",
|
|
68
|
+
description: "Local LLM via Ollama Docker service and chat endpoint",
|
|
69
|
+
},
|
|
64
70
|
{
|
|
65
71
|
id: "websocket",
|
|
66
72
|
label: "WebSockets",
|
|
@@ -121,6 +127,12 @@ const FEATURE_PATHS: Record<FeatureId, string[]> = {
|
|
|
121
127
|
"src/models/schemas/redis.ts",
|
|
122
128
|
"__tests__/redis.test.ts",
|
|
123
129
|
],
|
|
130
|
+
llama: [
|
|
131
|
+
"src/modules/llama",
|
|
132
|
+
"src/infra/llama",
|
|
133
|
+
"src/models/schemas/llama.ts",
|
|
134
|
+
"__tests__/llama.test.ts",
|
|
135
|
+
],
|
|
124
136
|
websocket: [
|
|
125
137
|
"src/modules/realtime",
|
|
126
138
|
"src/models/schemas/realtime.ts",
|
|
@@ -618,6 +630,18 @@ export function buildEnvExample(
|
|
|
618
630
|
);
|
|
619
631
|
}
|
|
620
632
|
|
|
633
|
+
if (selection.llama) {
|
|
634
|
+
lines.push(
|
|
635
|
+
"# Llama via Ollama (enabled by default in development; disabled in test)",
|
|
636
|
+
"# Start server: docker compose up -d llama",
|
|
637
|
+
"# Model is pulled automatically on first llama container start",
|
|
638
|
+
"# LLAMA_ENABLED=false",
|
|
639
|
+
"LLAMA_URL=http://localhost:11434",
|
|
640
|
+
"LLAMA_MODEL=llama3.2",
|
|
641
|
+
"",
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
|
|
621
645
|
if (selection.resend) {
|
|
622
646
|
lines.push(
|
|
623
647
|
"# Resend (disabled when RESEND_API_KEY is unset; always disabled in test)",
|
|
@@ -709,6 +733,12 @@ const DOCKER_OTEL_ENV =
|
|
|
709
733
|
const DOCKER_SPOTLIGHT_ENV =
|
|
710
734
|
"# Official Spotlight image; add overrides here if needed.\n";
|
|
711
735
|
|
|
736
|
+
const DOCKER_LLAMA_ENV = `# Ollama serves Llama models on port 11434
|
|
737
|
+
# Pulled automatically on first container start (see docker-entrypoint.sh)
|
|
738
|
+
OLLAMA_HOST=0.0.0.0
|
|
739
|
+
OLLAMA_MODEL=llama3.2
|
|
740
|
+
`;
|
|
741
|
+
|
|
712
742
|
function buildDockerPostgresEnv(packageName: string): string {
|
|
713
743
|
const name = toPostgresName(packageName);
|
|
714
744
|
return `POSTGRES_USER=${name}
|
|
@@ -743,6 +773,11 @@ function buildDockerAppEnv(
|
|
|
743
773
|
if (selection.sentry) {
|
|
744
774
|
lines.push("SENTRY_SPOTLIGHT=http://spotlight:8969/stream");
|
|
745
775
|
}
|
|
776
|
+
if (selection.llama) {
|
|
777
|
+
lines.push("LLAMA_ENABLED=true");
|
|
778
|
+
lines.push("LLAMA_URL=http://llama:11434");
|
|
779
|
+
lines.push("LLAMA_MODEL=llama3.2");
|
|
780
|
+
}
|
|
746
781
|
return `${lines.join("\n")}\n`;
|
|
747
782
|
}
|
|
748
783
|
|
|
@@ -760,6 +795,10 @@ function buildAppDependsOn(selection: FeatureSelection): string {
|
|
|
760
795
|
deps.push(` redis:
|
|
761
796
|
condition: service_healthy`);
|
|
762
797
|
}
|
|
798
|
+
if (selection.llama) {
|
|
799
|
+
deps.push(` llama:
|
|
800
|
+
condition: service_started`);
|
|
801
|
+
}
|
|
763
802
|
if (deps.length === 0) return "";
|
|
764
803
|
return ` depends_on:
|
|
765
804
|
${deps.join("\n")}
|
|
@@ -863,6 +902,24 @@ function generateDockerCompose(selection: FeatureSelection): string {
|
|
|
863
902
|
`
|
|
864
903
|
: "";
|
|
865
904
|
|
|
905
|
+
const llamaService = selection.llama
|
|
906
|
+
? `
|
|
907
|
+
llama:
|
|
908
|
+
build:
|
|
909
|
+
context: docker/llama
|
|
910
|
+
hostname: llama
|
|
911
|
+
ports:
|
|
912
|
+
- "\${LLAMA_PORT:-11434}:11434"
|
|
913
|
+
env_file:
|
|
914
|
+
- docker/llama/.env
|
|
915
|
+
volumes:
|
|
916
|
+
- llama_data:/root/.ollama
|
|
917
|
+
networks:
|
|
918
|
+
- app_network
|
|
919
|
+
restart: unless-stopped
|
|
920
|
+
`
|
|
921
|
+
: "";
|
|
922
|
+
|
|
866
923
|
return `services:
|
|
867
924
|
app:
|
|
868
925
|
build:
|
|
@@ -893,11 +950,19 @@ ${appDependsOn} healthcheck:
|
|
|
893
950
|
timeout: 300s
|
|
894
951
|
retries: 1
|
|
895
952
|
start_period: 90s
|
|
896
|
-
${postgresService}${kafkaService}${redisService}${otelService}${spotlightService}
|
|
953
|
+
${postgresService}${kafkaService}${redisService}${otelService}${spotlightService}${llamaService}
|
|
897
954
|
networks:
|
|
898
955
|
app_network:
|
|
899
956
|
driver: bridge
|
|
900
|
-
${selection
|
|
957
|
+
${buildComposeVolumes(selection)}`;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
function buildComposeVolumes(selection: FeatureSelection): string {
|
|
961
|
+
const volumes: string[] = [];
|
|
962
|
+
if (selection.postgres) volumes.push(" postgres_data:");
|
|
963
|
+
if (selection.llama) volumes.push(" llama_data:");
|
|
964
|
+
if (volumes.length === 0) return "";
|
|
965
|
+
return `\nvolumes:\n${volumes.join("\n")}\n`;
|
|
901
966
|
}
|
|
902
967
|
|
|
903
968
|
async function patchDockerCompose(
|
|
@@ -923,6 +988,9 @@ async function patchDockerCompose(
|
|
|
923
988
|
if (!selection.sentry) {
|
|
924
989
|
await removePaths(projectDir, ["docker/spotlight"]);
|
|
925
990
|
}
|
|
991
|
+
if (!selection.llama) {
|
|
992
|
+
await removePaths(projectDir, ["docker/llama"]);
|
|
993
|
+
}
|
|
926
994
|
|
|
927
995
|
await writeText(
|
|
928
996
|
projectDir,
|
|
@@ -952,6 +1020,9 @@ async function patchDockerCompose(
|
|
|
952
1020
|
if (selection.sentry) {
|
|
953
1021
|
await writeText(projectDir, "docker/spotlight/.env", DOCKER_SPOTLIGHT_ENV);
|
|
954
1022
|
}
|
|
1023
|
+
if (selection.llama) {
|
|
1024
|
+
await writeText(projectDir, "docker/llama/.env", DOCKER_LLAMA_ENV);
|
|
1025
|
+
}
|
|
955
1026
|
await writeText(
|
|
956
1027
|
projectDir,
|
|
957
1028
|
"docker-compose.yaml",
|