create-ragen-app 0.2.0 → 0.4.0

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 (39) hide show
  1. package/README.md +90 -7
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +218 -1
  4. package/dist/cli.js.map +1 -1
  5. package/dist/config-file.d.ts +14 -0
  6. package/dist/config-file.d.ts.map +1 -0
  7. package/dist/config-file.js +21 -0
  8. package/dist/config-file.js.map +1 -0
  9. package/dist/config-template.d.ts +30 -0
  10. package/dist/config-template.d.ts.map +1 -0
  11. package/dist/config-template.js +126 -0
  12. package/dist/config-template.js.map +1 -0
  13. package/dist/encryption-provider.d.ts +35 -0
  14. package/dist/encryption-provider.d.ts.map +1 -0
  15. package/dist/encryption-provider.js +63 -0
  16. package/dist/encryption-provider.js.map +1 -0
  17. package/dist/llm-provider.d.ts +17 -0
  18. package/dist/llm-provider.d.ts.map +1 -1
  19. package/dist/llm-provider.js +31 -1
  20. package/dist/llm-provider.js.map +1 -1
  21. package/dist/manifest.d.ts.map +1 -1
  22. package/dist/manifest.js +22 -4
  23. package/dist/manifest.js.map +1 -1
  24. package/dist/manual-setup.d.ts.map +1 -1
  25. package/dist/manual-setup.js +85 -16
  26. package/dist/manual-setup.js.map +1 -1
  27. package/dist/node-version.d.ts +54 -0
  28. package/dist/node-version.d.ts.map +1 -0
  29. package/dist/node-version.js +81 -0
  30. package/dist/node-version.js.map +1 -0
  31. package/dist/route-table.d.ts +31 -0
  32. package/dist/route-table.d.ts.map +1 -0
  33. package/dist/route-table.js +53 -0
  34. package/dist/route-table.js.map +1 -0
  35. package/dist/storage-provider.d.ts +49 -0
  36. package/dist/storage-provider.d.ts.map +1 -0
  37. package/dist/storage-provider.js +84 -0
  38. package/dist/storage-provider.js.map +1 -0
  39. package/package.json +2 -2
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CONFIG_FILENAME = void 0;
4
+ exports.renderRagenConfig = renderRagenConfig;
5
+ /**
6
+ * The whole `ragen.config.ts`, rendered.
7
+ *
8
+ * This replaced patching a marked region in the cloned file, after that
9
+ * approach produced four separate defects in a day: a substring search that
10
+ * matched the end marker inside the start marker, a marker line that carried
11
+ * explanatory prose and so matched nothing once the search was tightened, and
12
+ * two duplicate-region layouts that each mangled the file in a different way.
13
+ * Every one was a case of locating a region inside arbitrary text, and the
14
+ * space of ways that goes wrong is not something a fixture can be trusted to
15
+ * explore — the third defect reached CI precisely because every fixture
16
+ * agreed with the others and none agreed with the file being shipped.
17
+ *
18
+ * Rendering the whole file removes the operation entirely. There is nothing
19
+ * to find, nothing to preserve, and no malformed input: the installer writes
20
+ * what it means.
21
+ *
22
+ * The cost is that this template must carry the groups the wizard never asks
23
+ * about, and could drift from the file the repository ships. It cannot:
24
+ * `ragen.config.ts` at the repository root **is generated from this function**
25
+ * (`npm run config:template`), and
26
+ * `tests/architecture/ragen-config-is-generated.test.ts` compares them. One
27
+ * source, one artifact, checked — the same arrangement as the published
28
+ * configuration reference.
29
+ */
30
+ exports.CONFIG_FILENAME = 'ragen.config.ts';
31
+ /**
32
+ * A required field is typed `string`, so `process.env.X` alone does not
33
+ * compile — it is `string | undefined`. The fallback is a blank rather than a
34
+ * non-null assertion because a blank is *true*: the variable may genuinely be
35
+ * missing, and every reader in `@ragenai/env` treats blank as unset, so the
36
+ * boot-time check reports it instead of a `!` hiding it until something
37
+ * dereferences undefined.
38
+ */
39
+ function renderField({ field, envVar, required }) {
40
+ const value = required
41
+ ? `process.env.${envVar} ?? ''`
42
+ : `process.env.${envVar}`;
43
+ return ` ${field}: ${value},`;
44
+ }
45
+ function renderGroup(group, provider, fields, comment) {
46
+ return [
47
+ ` ${group}: {`,
48
+ ...(comment ? [` // ${comment}`] : []),
49
+ ` provider: '${provider}',`,
50
+ ...fields.map(renderField),
51
+ ' },',
52
+ ];
53
+ }
54
+ const HEADER = `import { defineConfig } from '@ragenai/env';
55
+
56
+ /**
57
+ * The configuration this deployment was created with.
58
+ *
59
+ * Generated by \`create-ragen-app\`, which writes it once when the project is
60
+ * scaffolded and never again — so in a scaffolded project this is yours to
61
+ * edit.
62
+ *
63
+ * In the Ragen repository itself it is an artifact: regenerate it with
64
+ * \`npm run config:template\` and make changes in
65
+ * \`packages/create-ragen-app/src/config-template.ts\`, or the next scaffold
66
+ * discards them.
67
+ *
68
+ * ADR-37 declined a \`ragen.config.ts\` the apps would *read* instead of the
69
+ * environment, and that still holds: a secret does not belong in git, and
70
+ * compose, the Dockerfiles and Railway only speak environment variables.
71
+ * **Nothing reads this file at runtime.** It is the structure and the
72
+ * defaulting, with every value still resolved from \`process.env\` — which is
73
+ * why a fresh clone works with the minimum \`.env.local\` AGENTS.md documents,
74
+ * and why the fallbacks below are the same ones the code already applies.
75
+ *
76
+ * What it is for: choosing a provider makes that provider's variables
77
+ * mandatory *in the editor*. \`storage: { provider: 's3' }\` with no bucket does
78
+ * not compile. \`npm run typecheck:config\` is what makes that real — without
79
+ * it this file would be checked by nothing, since the repository has no root
80
+ * \`tsconfig.json\`.
81
+ *
82
+ * The shapes come from \`packages/env/src/provider-seams.ts\` and
83
+ * \`config-groups.ts\`, the same tables the boot-time check reads.
84
+ */
85
+ export default defineConfig({
86
+ database: {
87
+ url:
88
+ process.env.DATABASE_URL ??
89
+ 'postgresql://postgres:pass123@localhost:55432/ragen',
90
+ },
91
+
92
+ gateway: {
93
+ // Every model call goes through LiteLLM (ADR-04).
94
+ url: process.env.LITELLM_PROXY_URL ?? 'http://localhost:4000',
95
+ masterKey: process.env.LITELLM_MASTER_KEY,
96
+ },
97
+
98
+ vectorStore: {
99
+ // Qdrant is the only supported vector store (ADR-31).
100
+ url: process.env.QDRANT_URL ?? 'http://localhost:6333',
101
+ apiKey: process.env.QDRANT_API_KEY,
102
+ },
103
+
104
+ models: {
105
+ chat: process.env.DEFAULT_MODEL ?? 'gemini-3-flash-preview',
106
+ // Do not upgrade without approval — see AGENTS.md, "Model Defaults".
107
+ rephrase: process.env.REPHRASE_MODEL ?? 'gemini-2.5-flash',
108
+ summary: process.env.SUMMARY_MODEL ?? 'gemini-2.5-flash',
109
+ embeddings: process.env.EMBEDDINGS_MODEL,
110
+ // Changing this after documents exist invalidates the collection.
111
+ vectorSize: process.env.VECTOR_SIZE,
112
+ },
113
+
114
+ `;
115
+ function renderRagenConfig(storage, encryption) {
116
+ const lines = [
117
+ ...renderGroup('storage', storage.provider, storage.configFields, storage.provider === 'local'
118
+ ? 'ADR-27: local by default, so a fresh clone runs without a cloud account.'
119
+ : undefined),
120
+ ];
121
+ if (encryption.provider !== 'none') {
122
+ lines.push('', ...renderGroup('encryption', encryption.provider, encryption.configFields));
123
+ }
124
+ return `${HEADER}${lines.join('\n')}\n});\n`;
125
+ }
126
+ //# sourceMappingURL=config-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-template.js","sourceRoot":"","sources":["../src/config-template.ts"],"names":[],"mappings":";;;AA2HA,8CA2BC;AAnJD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEU,QAAA,eAAe,GAAG,iBAAiB,CAAC;AAEjD;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAe;IAC3D,MAAM,KAAK,GAAG,QAAQ;QACpB,CAAC,CAAC,eAAe,MAAM,QAAQ;QAC/B,CAAC,CAAC,eAAe,MAAM,EAAE,CAAC;IAC5B,OAAO,OAAO,KAAK,KAAK,KAAK,GAAG,CAAC;AACnC,CAAC;AAED,SAAS,WAAW,CAClB,KAAa,EACb,QAAgB,EAChB,MAAqB,EACrB,OAAgB;IAEhB,OAAO;QACL,KAAK,KAAK,KAAK;QACf,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,kBAAkB,QAAQ,IAAI;QAC9B,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC;QAC1B,MAAM;KACP,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4Dd,CAAC;AAEF,SAAgB,iBAAiB,CAC/B,OAAyB,EACzB,UAA+B;IAE/B,MAAM,KAAK,GAAG;QACZ,GAAG,WAAW,CACZ,SAAS,EACT,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,YAAY,EACpB,OAAO,CAAC,QAAQ,KAAK,OAAO;YAC1B,CAAC,CAAC,0EAA0E;YAC5E,CAAC,CAAC,SAAS,CACd;KACF,CAAC;IAEF,IAAI,UAAU,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CACR,EAAE,EACF,GAAG,WAAW,CACZ,YAAY,EACZ,UAAU,CAAC,QAAQ,EACnB,UAAU,CAAC,YAAY,CACxB,CACF,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { ConfigField } from './storage-provider';
2
+ /**
3
+ * Encryption at rest for thread messages and PII (ADR-02, ADR-06).
4
+ *
5
+ * The wizard skipped this too, and the cost of skipping is asymmetric:
6
+ * turning encryption *on* later leaves everything written before it in
7
+ * plaintext, because nothing re-encrypts history. So the one moment it is
8
+ * free to decide is the moment the install is created.
9
+ *
10
+ * `local` is offered first because it costs the user nothing —
11
+ * `generateSecret()` already produces a 64-character hex string, which is
12
+ * exactly what `parseMasterKey` in `@ragenai/crypto` accepts. No account, no
13
+ * console, no copy-paste.
14
+ *
15
+ * The variable names mirror `ENCRYPTION_SEAM` in `@ragenai/env`, copied rather
16
+ * than imported for the reason given in `storage-provider.ts`, and held to the
17
+ * original by `tests/architecture/create-ragen-app-knows-the-provider-seams.test.ts`.
18
+ */
19
+ export type EncryptionChoice = 'none' | 'local' | 'scaleway' | 'kms';
20
+ export declare const ENCRYPTION_LABELS: Record<EncryptionChoice, string>;
21
+ export interface EncryptionAnswers {
22
+ /** Scaleway: Key Manager key id. KMS: the key id or ARN. */
23
+ keyId: string;
24
+ /** Scaleway only. */
25
+ apiKey: string;
26
+ }
27
+ export interface EncryptionSelection {
28
+ provider: EncryptionChoice;
29
+ envUpdates: Record<string, string>;
30
+ configFields: ConfigField[];
31
+ /** True when the wizard minted the key, so the CLI can say where it went. */
32
+ generatedKey: boolean;
33
+ }
34
+ export declare function resolveEncryptionSelection(provider: EncryptionChoice, answers?: EncryptionAnswers): EncryptionSelection;
35
+ //# sourceMappingURL=encryption-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption-provider.d.ts","sourceRoot":"","sources":["../src/encryption-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,KAAK,CAAC;AAErE,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAK9D,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,6EAA6E;IAC7E,YAAY,EAAE,OAAO,CAAC;CACvB;AAOD,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,mBAAmB,CAkDrB"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ENCRYPTION_LABELS = void 0;
4
+ exports.resolveEncryptionSelection = resolveEncryptionSelection;
5
+ const secrets_1 = require("./secrets");
6
+ exports.ENCRYPTION_LABELS = {
7
+ local: 'Yes — generate a key for me (recommended)',
8
+ scaleway: 'Yes — Scaleway Key Manager (I have a key id)',
9
+ kms: 'Yes — AWS KMS (I have a key id)',
10
+ none: 'No — store messages and documents in plaintext',
11
+ };
12
+ const NOTHING = {
13
+ envUpdates: {},
14
+ configFields: [],
15
+ };
16
+ function resolveEncryptionSelection(provider, answers) {
17
+ if (provider === 'none') {
18
+ // Deliberately writes nothing rather than `ENCRYPTION_PROVIDER=none`:
19
+ // there is no such provider, and `@ragenai/crypto` decides by looking for
20
+ // credentials. An unset variable is the honest way to say "not
21
+ // configured", and it is what a deployed environment refuses to start on.
22
+ return { provider, ...NOTHING, generatedKey: false };
23
+ }
24
+ if (provider === 'local') {
25
+ return {
26
+ provider,
27
+ envUpdates: {
28
+ ENCRYPTION_PROVIDER: 'local',
29
+ ENCRYPTION_MASTER_KEY: (0, secrets_1.generateSecret)(),
30
+ },
31
+ configFields: [
32
+ { field: 'masterKey', envVar: 'ENCRYPTION_MASTER_KEY', required: true },
33
+ ],
34
+ generatedKey: true,
35
+ };
36
+ }
37
+ const keyId = answers?.keyId.trim() ?? '';
38
+ const apiKey = answers?.apiKey.trim() ?? '';
39
+ if (provider === 'kms') {
40
+ return {
41
+ provider,
42
+ envUpdates: { ENCRYPTION_PROVIDER: 'kms', AWS_KMS_KEY_ID: keyId },
43
+ configFields: [
44
+ { field: 'keyId', envVar: 'AWS_KMS_KEY_ID', required: true },
45
+ ],
46
+ generatedKey: false,
47
+ };
48
+ }
49
+ return {
50
+ provider: 'scaleway',
51
+ envUpdates: {
52
+ ENCRYPTION_PROVIDER: 'scaleway',
53
+ SCW_KEY_MANAGER_KEY_ID: keyId,
54
+ SCW_API_KEY: apiKey,
55
+ },
56
+ configFields: [
57
+ { field: 'keyId', envVar: 'SCW_KEY_MANAGER_KEY_ID', required: true },
58
+ { field: 'apiKey', envVar: 'SCW_API_KEY', required: true },
59
+ ],
60
+ generatedKey: false,
61
+ };
62
+ }
63
+ //# sourceMappingURL=encryption-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption-provider.js","sourceRoot":"","sources":["../src/encryption-provider.ts"],"names":[],"mappings":";;;AAkDA,gEAqDC;AAvGD,uCAA2C;AAuB9B,QAAA,iBAAiB,GAAqC;IACjE,KAAK,EAAE,2CAA2C;IAClD,QAAQ,EAAE,8CAA8C;IACxD,GAAG,EAAE,iCAAiC;IACtC,IAAI,EAAE,gDAAgD;CACvD,CAAC;AAiBF,MAAM,OAAO,GAA6D;IACxE,UAAU,EAAE,EAAE;IACd,YAAY,EAAE,EAAE;CACjB,CAAC;AAEF,SAAgB,0BAA0B,CACxC,QAA0B,EAC1B,OAA2B;IAE3B,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,sEAAsE;QACtE,0EAA0E;QAC1E,+DAA+D;QAC/D,0EAA0E;QAC1E,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;IACvD,CAAC;IAED,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO;YACL,QAAQ;YACR,UAAU,EAAE;gBACV,mBAAmB,EAAE,OAAO;gBAC5B,qBAAqB,EAAE,IAAA,wBAAc,GAAE;aACxC;YACD,YAAY,EAAE;gBACZ,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,uBAAuB,EAAE,QAAQ,EAAE,IAAI,EAAE;aACxE;YACD,YAAY,EAAE,IAAI;SACnB,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IAC1C,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IAE5C,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QACvB,OAAO;YACL,QAAQ;YACR,UAAU,EAAE,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE;YACjE,YAAY,EAAE;gBACZ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,IAAI,EAAE;aAC7D;YACD,YAAY,EAAE,KAAK;SACpB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,UAAU;QACpB,UAAU,EAAE;YACV,mBAAmB,EAAE,UAAU;YAC/B,sBAAsB,EAAE,KAAK;YAC7B,WAAW,EAAE,MAAM;SACpB;QACD,YAAY,EAAE;YACZ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,wBAAwB,EAAE,QAAQ,EAAE,IAAI,EAAE;YACpE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;SAC3D;QACD,YAAY,EAAE,KAAK;KACpB,CAAC;AACJ,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { LiteLLMModelEntry } from './litellm-config';
2
+ import type { RouteTableEntry } from './route-table';
2
3
  /**
3
4
  * The `infra/litellm/config.yaml` shipped in the repo only wires Azure
4
5
  * OpenAI, AWS Bedrock, Google Vertex and Scaleway — none of which a new
@@ -9,6 +10,8 @@ export type LlmProviderChoice = 'openai' | 'anthropic';
9
10
  export interface LlmEmbeddingsConfig {
10
11
  modelName: string;
11
12
  litellmModel: string;
13
+ /** The upstream's own name, for the route table. */
14
+ upstreamModel: string;
12
15
  /** Output dimensionality — must match `VECTOR_SIZE`, see rag-core's vector contract. */
13
16
  vectorSize: number;
14
17
  }
@@ -17,6 +20,15 @@ export interface LlmProviderConfig {
17
20
  apiKeyEnvVar: string;
18
21
  modelName: string;
19
22
  litellmModel: string;
23
+ /**
24
+ * The `@ragenai/llm-gateway` provider that serves this key directly, and the
25
+ * upstream's own name for the model. Both providers the wizard offers have
26
+ * one, so a scaffolded install calls the provider itself — the same default
27
+ * every other deployment gets — rather than routing through a proxy it only
28
+ * runs because the wizard configured one.
29
+ */
30
+ gatewayProvider: string;
31
+ upstreamModel: string;
20
32
  /**
21
33
  * Undefined for a provider with no embeddings API of its own. Chat still
22
34
  * works; the knowledge base does not, because retrieval has nothing to
@@ -30,6 +42,11 @@ export declare const LLM_PROVIDERS: Record<LlmProviderChoice, LlmProviderConfig>
30
42
  export interface LlmProviderChoiceResult {
31
43
  envUpdates: Record<string, string>;
32
44
  liteLLMEntries: LiteLLMModelEntry[];
45
+ /**
46
+ * The route table this installation gets. Written over the one shipped in
47
+ * the repository, which names providers a new install has no keys for.
48
+ */
49
+ routes: RouteTableEntry[];
33
50
  /** False when the picked provider cannot serve embeddings — the caller warns. */
34
51
  embeddingsConfigured: boolean;
35
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"llm-provider.d.ts","sourceRoot":"","sources":["../src/llm-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,wFAAwF;IACxF,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,iBAAiB,EAAE,iBAAiB,CAyBtE,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,cAAc,EAAE,iBAAiB,EAAE,CAAC;IACpC,iFAAiF;IACjF,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,MAAM,GACb,uBAAuB,CAwCzB"}
1
+ {"version":3,"file":"llm-provider.d.ts","sourceRoot":"","sources":["../src/llm-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;IACtB,wFAAwF;IACxF,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,iBAAiB,EAAE,iBAAiB,CAiCtE,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,cAAc,EAAE,iBAAiB,EAAE,CAAC;IACpC;;;OAGG;IACH,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,iFAAiF;IACjF,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,MAAM,GACb,uBAAuB,CA+DzB"}
@@ -8,9 +8,12 @@ exports.LLM_PROVIDERS = {
8
8
  apiKeyEnvVar: 'OPENAI_API_KEY',
9
9
  modelName: 'gpt-4o-mini',
10
10
  litellmModel: 'openai/gpt-4o-mini',
11
+ gatewayProvider: 'openai',
12
+ upstreamModel: 'gpt-4o-mini',
11
13
  embeddings: {
12
14
  modelName: 'text-embedding-3-small',
13
15
  litellmModel: 'openai/text-embedding-3-small',
16
+ upstreamModel: 'text-embedding-3-small',
14
17
  vectorSize: 1536,
15
18
  },
16
19
  },
@@ -24,8 +27,13 @@ exports.LLM_PROVIDERS = {
24
27
  // Bedrock traffic under Bedrock's catalog metadata.
25
28
  modelName: 'claude-haiku-4-5-direct',
26
29
  litellmModel: 'anthropic/claude-haiku-4-5-20251001',
30
+ gatewayProvider: 'anthropic',
31
+ upstreamModel: 'claude-haiku-4-5-20251001',
27
32
  // Anthropic ships no embeddings endpoint, so there is nothing to point
28
- // EMBEDDINGS_MODEL at with this key alone.
33
+ // EMBEDDINGS_MODEL at with this key alone. The gateway says the same
34
+ // thing in its own shape: `anthropic` has no entry in
35
+ // EMBEDDING_PROVIDER_FACTORIES, and a route pointing there raises
36
+ // EmbeddingsUnsupportedError rather than failing inside the AI SDK.
29
37
  },
30
38
  };
31
39
  function resolveLlmProviderChoice(choice, apiKey) {
@@ -33,6 +41,12 @@ function resolveLlmProviderChoice(choice, apiKey) {
33
41
  const envUpdates = {
34
42
  [config.apiKeyEnvVar]: apiKey,
35
43
  DEFAULT_MODEL: config.modelName,
44
+ // Overrides the manifest's `litellm`, which is the baseline for the one
45
+ // path that reaches neither branch here: "I'll configure LiteLLM myself".
46
+ LLM_GATEWAY: 'native',
47
+ // Not the gateway. This names the pricing namespace `AiUsage` writes
48
+ // against, where the whole catalogue lives under `litellm`; the provider
49
+ // that actually served a turn is recorded separately as `servedBy`.
36
50
  DEFAULT_MODEL_PROVIDER: 'litellm',
37
51
  // .env.example ships gemini-2.5-flash here, which needs Vertex
38
52
  // credentials. Multi-query expansion is on by default (ADR-15), so
@@ -47,6 +61,16 @@ function resolveLlmProviderChoice(choice, apiKey) {
47
61
  apiKeyEnvVar: config.apiKeyEnvVar,
48
62
  },
49
63
  ];
64
+ // Written as well as the route table, and deliberately: `docker compose up`
65
+ // starts LiteLLM whatever `LLM_GATEWAY` says, so configuring both makes
66
+ // `LLM_GATEWAY=litellm` a working rollback rather than a broken one.
67
+ const routes = [
68
+ {
69
+ modelName: config.modelName,
70
+ provider: config.gatewayProvider,
71
+ model: config.upstreamModel,
72
+ },
73
+ ];
50
74
  if (config.embeddings) {
51
75
  envUpdates.EMBEDDINGS_MODEL = config.embeddings.modelName;
52
76
  // VECTOR_SIZE and EMBEDDINGS_MODEL have to agree or Qdrant rejects every
@@ -58,10 +82,16 @@ function resolveLlmProviderChoice(choice, apiKey) {
58
82
  model: config.embeddings.litellmModel,
59
83
  apiKeyEnvVar: config.apiKeyEnvVar,
60
84
  });
85
+ routes.push({
86
+ modelName: config.embeddings.modelName,
87
+ provider: config.gatewayProvider,
88
+ model: config.embeddings.upstreamModel,
89
+ });
61
90
  }
62
91
  return {
63
92
  envUpdates,
64
93
  liteLLMEntries,
94
+ routes,
65
95
  embeddingsConfigured: Boolean(config.embeddings),
66
96
  };
67
97
  }
@@ -1 +1 @@
1
- {"version":3,"file":"llm-provider.js","sourceRoot":"","sources":["../src/llm-provider.ts"],"names":[],"mappings":";;;AAkEA,4DA2CC;AA7EY,QAAA,aAAa,GAAiD;IACzE,MAAM,EAAE;QACN,KAAK,EAAE,QAAQ;QACf,YAAY,EAAE,gBAAgB;QAC9B,SAAS,EAAE,aAAa;QACxB,YAAY,EAAE,oBAAoB;QAClC,UAAU,EAAE;YACV,SAAS,EAAE,wBAAwB;YACnC,YAAY,EAAE,+BAA+B;YAC7C,UAAU,EAAE,IAAI;SACjB;KACF;IACD,SAAS,EAAE;QACT,KAAK,EAAE,WAAW;QAClB,YAAY,EAAE,mBAAmB;QACjC,gFAAgF;QAChF,uEAAuE;QACvE,qEAAqE;QACrE,sEAAsE;QACtE,oDAAoD;QACpD,SAAS,EAAE,yBAAyB;QACpC,YAAY,EAAE,qCAAqC;QACnD,uEAAuE;QACvE,2CAA2C;KAC5C;CACF,CAAC;AASF,SAAgB,wBAAwB,CACtC,MAAyB,EACzB,MAAc;IAEd,MAAM,MAAM,GAAG,qBAAa,CAAC,MAAM,CAAC,CAAC;IAErC,MAAM,UAAU,GAA2B;QACzC,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM;QAC7B,aAAa,EAAE,MAAM,CAAC,SAAS;QAC/B,sBAAsB,EAAE,SAAS;QACjC,+DAA+D;QAC/D,mEAAmE;QACnE,uEAAuE;QACvE,kDAAkD;QAClD,cAAc,EAAE,MAAM,CAAC,SAAS;KACjC,CAAC;IAEF,MAAM,cAAc,GAAwB;QAC1C;YACE,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,KAAK,EAAE,MAAM,CAAC,YAAY;YAC1B,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC;KACF,CAAC;IAEF,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,UAAU,CAAC,gBAAgB,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC;QAC1D,yEAAyE;QACzE,sEAAsE;QACtE,qDAAqD;QACrD,UAAU,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC9D,cAAc,CAAC,IAAI,CAAC;YAClB,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,SAAS;YACtC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,YAAY;YACrC,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,UAAU;QACV,cAAc;QACd,oBAAoB,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;KACjD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"llm-provider.js","sourceRoot":"","sources":["../src/llm-provider.ts"],"names":[],"mappings":";;;AA2FA,4DAkEC;AAjHY,QAAA,aAAa,GAAiD;IACzE,MAAM,EAAE;QACN,KAAK,EAAE,QAAQ;QACf,YAAY,EAAE,gBAAgB;QAC9B,SAAS,EAAE,aAAa;QACxB,YAAY,EAAE,oBAAoB;QAClC,eAAe,EAAE,QAAQ;QACzB,aAAa,EAAE,aAAa;QAC5B,UAAU,EAAE;YACV,SAAS,EAAE,wBAAwB;YACnC,YAAY,EAAE,+BAA+B;YAC7C,aAAa,EAAE,wBAAwB;YACvC,UAAU,EAAE,IAAI;SACjB;KACF;IACD,SAAS,EAAE;QACT,KAAK,EAAE,WAAW;QAClB,YAAY,EAAE,mBAAmB;QACjC,gFAAgF;QAChF,uEAAuE;QACvE,qEAAqE;QACrE,sEAAsE;QACtE,oDAAoD;QACpD,SAAS,EAAE,yBAAyB;QACpC,YAAY,EAAE,qCAAqC;QACnD,eAAe,EAAE,WAAW;QAC5B,aAAa,EAAE,2BAA2B;QAC1C,uEAAuE;QACvE,qEAAqE;QACrE,sDAAsD;QACtD,kEAAkE;QAClE,oEAAoE;KACrE;CACF,CAAC;AAcF,SAAgB,wBAAwB,CACtC,MAAyB,EACzB,MAAc;IAEd,MAAM,MAAM,GAAG,qBAAa,CAAC,MAAM,CAAC,CAAC;IAErC,MAAM,UAAU,GAA2B;QACzC,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM;QAC7B,aAAa,EAAE,MAAM,CAAC,SAAS;QAC/B,wEAAwE;QACxE,0EAA0E;QAC1E,WAAW,EAAE,QAAQ;QACrB,qEAAqE;QACrE,yEAAyE;QACzE,oEAAoE;QACpE,sBAAsB,EAAE,SAAS;QACjC,+DAA+D;QAC/D,mEAAmE;QACnE,uEAAuE;QACvE,kDAAkD;QAClD,cAAc,EAAE,MAAM,CAAC,SAAS;KACjC,CAAC;IAEF,MAAM,cAAc,GAAwB;QAC1C;YACE,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,KAAK,EAAE,MAAM,CAAC,YAAY;YAC1B,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC;KACF,CAAC;IAEF,4EAA4E;IAC5E,wEAAwE;IACxE,qEAAqE;IACrE,MAAM,MAAM,GAAsB;QAChC;YACE,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,QAAQ,EAAE,MAAM,CAAC,eAAe;YAChC,KAAK,EAAE,MAAM,CAAC,aAAa;SAC5B;KACF,CAAC;IAEF,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,UAAU,CAAC,gBAAgB,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC;QAC1D,yEAAyE;QACzE,sEAAsE;QACtE,qDAAqD;QACrD,UAAU,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC9D,cAAc,CAAC,IAAI,CAAC;YAClB,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,SAAS;YACtC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,YAAY;YACrC,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC;YACV,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,SAAS;YACtC,QAAQ,EAAE,MAAM,CAAC,eAAe;YAChC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,aAAa;SACvC,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,UAAU;QACV,cAAc;QACd,MAAM;QACN,oBAAoB,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;KACjD,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzC,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAEpE,eAAO,MAAM,QAAQ,EAAE,aAAa,EAqEnC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,aAAa,EAAE,CAEnE"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzC,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAEpE,eAAO,MAAM,QAAQ,EAAE,aAAa,EAuFnC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,aAAa,EAAE,CAEnE"}
package/dist/manifest.js CHANGED
@@ -63,6 +63,22 @@ exports.MANIFEST = [
63
63
  targets: ['root', 'admin'],
64
64
  },
65
65
  // --- Local-dev defaults that correct a stale example value ---
66
+ {
67
+ // The baseline, and `resolveLlmProviderChoice` overrides it with `native`
68
+ // whenever a provider key is actually configured — which is both branches
69
+ // the wizard offers.
70
+ //
71
+ // What is left is the third path: "I'll configure LiteLLM myself". That
72
+ // one writes no route table, and the table shipped in the repository names
73
+ // Azure, Bedrock, Vertex and Scaleway — providers a fresh install has no
74
+ // credentials for. Inheriting the `native` default there would make every
75
+ // model call fail on the first question, so this pins the proxy the manual
76
+ // guide then tells them to configure.
77
+ key: 'LLM_GATEWAY',
78
+ strategy: 'local-default',
79
+ targets: ['root'],
80
+ value: 'litellm',
81
+ },
66
82
  {
67
83
  // Ships commented out, which leaves apps/web sending no Authorization
68
84
  // header while docker-compose.yml starts the proxy *with* a master key
@@ -82,10 +98,12 @@ exports.MANIFEST = [
82
98
  value: 'sk-litellm-dev-key',
83
99
  },
84
100
  {
85
- // docker-compose.yml maps Postgres to host port 55432, not the 5432 that
86
- // both .env.example files show — a native/other Postgres on 5432 would
87
- // otherwise silently answer instead of the container. See
88
- // docs/lessons.md.
101
+ // docker-compose.yml maps Postgres to host port 55432. A native or other
102
+ // Postgres on 5432 would otherwise silently answer instead of the
103
+ // container, and report success against the wrong database. The
104
+ // `.env.example` files used to disagree with this value; they no longer
105
+ // do, and `tests/architecture/docs-name-the-published-service-ports.test.ts`
106
+ // keeps it that way. See docs/lessons.md.
89
107
  key: 'DATABASE_URL',
90
108
  strategy: 'local-default',
91
109
  targets: ['root', 'admin'],
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;;AA0FH,4CAEC;AAzEY,QAAA,QAAQ,GAAoB;IACvC,oDAAoD;IACpD,EAAE,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE;IACrE,EAAE,GAAG,EAAE,oBAAoB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE;IAC7E;QACE,GAAG,EAAE,0BAA0B;QAC/B,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB;IACD;QACE,GAAG,EAAE,qBAAqB;QAC1B,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB;IACD;QACE,6DAA6D;QAC7D,sEAAsE;QACtE,0DAA0D;QAC1D,GAAG,EAAE,mBAAmB;QACxB,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB;IACD;QACE,GAAG,EAAE,oBAAoB;QACzB,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,OAAO,CAAC;KACnB;IAED,yDAAyD;IACzD;QACE,yEAAyE;QACzE,mDAAmD;QACnD,oEAAoE;QACpE,0EAA0E;QAC1E,0BAA0B;QAC1B,GAAG,EAAE,qBAAqB;QAC1B,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;KAC3B;IAED,gEAAgE;IAChE;QACE,sEAAsE;QACtE,uEAAuE;QACvE,uEAAuE;QACvE,mEAAmE;QACnE,eAAe;QACf,EAAE;QACF,sEAAsE;QACtE,wEAAwE;QACxE,kEAAkE;QAClE,uEAAuE;QACvE,uEAAuE;QACvE,kEAAkE;QAClE,GAAG,EAAE,oBAAoB;QACzB,QAAQ,EAAE,eAAe;QACzB,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,KAAK,EAAE,oBAAoB;KAC5B;IACD;QACE,yEAAyE;QACzE,uEAAuE;QACvE,0DAA0D;QAC1D,mBAAmB;QACnB,GAAG,EAAE,cAAc;QACnB,QAAQ,EAAE,eAAe;QACzB,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;QAC1B,KAAK,EAAE,qDAAqD;KAC7D;CACF,CAAC;AAEF,SAAgB,gBAAgB,CAAC,MAAiB;IAChD,OAAO,gBAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACpE,CAAC"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;;AA4GH,4CAEC;AA3FY,QAAA,QAAQ,GAAoB;IACvC,oDAAoD;IACpD,EAAE,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE;IACrE,EAAE,GAAG,EAAE,oBAAoB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE;IAC7E;QACE,GAAG,EAAE,0BAA0B;QAC/B,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB;IACD;QACE,GAAG,EAAE,qBAAqB;QAC1B,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB;IACD;QACE,6DAA6D;QAC7D,sEAAsE;QACtE,0DAA0D;QAC1D,GAAG,EAAE,mBAAmB;QACxB,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB;IACD;QACE,GAAG,EAAE,oBAAoB;QACzB,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,OAAO,CAAC;KACnB;IAED,yDAAyD;IACzD;QACE,yEAAyE;QACzE,mDAAmD;QACnD,oEAAoE;QACpE,0EAA0E;QAC1E,0BAA0B;QAC1B,GAAG,EAAE,qBAAqB;QAC1B,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;KAC3B;IAED,gEAAgE;IAChE;QACE,0EAA0E;QAC1E,0EAA0E;QAC1E,qBAAqB;QACrB,EAAE;QACF,wEAAwE;QACxE,2EAA2E;QAC3E,yEAAyE;QACzE,0EAA0E;QAC1E,2EAA2E;QAC3E,sCAAsC;QACtC,GAAG,EAAE,aAAa;QAClB,QAAQ,EAAE,eAAe;QACzB,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,KAAK,EAAE,SAAS;KACjB;IACD;QACE,sEAAsE;QACtE,uEAAuE;QACvE,uEAAuE;QACvE,mEAAmE;QACnE,eAAe;QACf,EAAE;QACF,sEAAsE;QACtE,wEAAwE;QACxE,kEAAkE;QAClE,uEAAuE;QACvE,uEAAuE;QACvE,kEAAkE;QAClE,GAAG,EAAE,oBAAoB;QACzB,QAAQ,EAAE,eAAe;QACzB,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,KAAK,EAAE,oBAAoB;KAC5B;IACD;QACE,yEAAyE;QACzE,kEAAkE;QAClE,gEAAgE;QAChE,wEAAwE;QACxE,6EAA6E;QAC7E,0CAA0C;QAC1C,GAAG,EAAE,cAAc;QACnB,QAAQ,EAAE,eAAe;QACzB,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;QAC1B,KAAK,EAAE,qDAAqD;KAC7D;CACF,CAAC;AAEF,SAAgB,gBAAgB,CAAC,MAAiB;IAChD,OAAO,gBAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACpE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"manual-setup.d.ts","sourceRoot":"","sources":["../src/manual-setup.ts"],"names":[],"mappings":"AAsEA,wBAAgB,0BAA0B,IAAI,MAAM,CAkCnD"}
1
+ {"version":3,"file":"manual-setup.d.ts","sourceRoot":"","sources":["../src/manual-setup.ts"],"names":[],"mappings":"AAgJA,wBAAgB,0BAA0B,IAAI,MAAM,CAoCnD"}
@@ -16,10 +16,18 @@ function providerSection(choice) {
16
16
  const config = llm_provider_1.LLM_PROVIDERS[choice];
17
17
  const envLines = [
18
18
  `${config.apiKeyEnvVar}=<your ${config.label} key>`,
19
+ // The wizard writes this, so the guide must too — otherwise following it
20
+ // by hand produces a proxy install where the wizard produces a direct one.
21
+ 'LLM_GATEWAY=native',
19
22
  'DEFAULT_MODEL_PROVIDER=litellm',
20
23
  `DEFAULT_MODEL=${config.modelName}`,
21
24
  `REPHRASE_MODEL=${config.modelName}`,
22
25
  ];
26
+ const routeLines = [
27
+ ` ${config.modelName}:`,
28
+ ` provider: ${config.gatewayProvider}`,
29
+ ` model: ${config.upstreamModel}`,
30
+ ];
23
31
  const yamlLines = [
24
32
  ` - model_name: ${config.modelName}`,
25
33
  ' litellm_params:',
@@ -29,6 +37,7 @@ function providerSection(choice) {
29
37
  if (config.embeddings) {
30
38
  envLines.push(`EMBEDDINGS_MODEL=${config.embeddings.modelName}`, `VECTOR_SIZE=${config.embeddings.vectorSize}`);
31
39
  yamlLines.push(` - model_name: ${config.embeddings.modelName}`, ' litellm_params:', ` model: ${config.embeddings.litellmModel}`, ` api_key: os.environ/${config.apiKeyEnvVar}`);
40
+ routeLines.push(` ${config.embeddings.modelName}:`, ` provider: ${config.gatewayProvider}`, ` model: ${config.embeddings.upstreamModel}`);
32
41
  }
33
42
  return [
34
43
  `### ${config.label}`,
@@ -39,20 +48,78 @@ function providerSection(choice) {
39
48
  ...envLines,
40
49
  '```',
41
50
  '',
42
- '`infra/litellm/config.yaml`, under the existing `model_list:` key:',
51
+ '`infra/llm-gateway/routes.yaml` — replace the `routes:` block with:',
52
+ '',
53
+ '```yaml',
54
+ 'routes:',
55
+ ...routeLines,
56
+ '```',
57
+ '',
58
+ 'The table shipped in the repository routes to Azure, Bedrock, Vertex and',
59
+ 'Scaleway. Those entries are not wrong, they are simply not yours.',
60
+ '',
61
+ `<details><summary>Prefer to run a proxy instead?</summary>`,
62
+ '',
63
+ 'Set `LLM_GATEWAY=litellm` rather than `native`, leave the route table',
64
+ 'alone, and add this under the existing `model_list:` key in',
65
+ '`infra/litellm/config.yaml`:',
43
66
  '',
44
67
  '```yaml',
45
68
  ...yamlLines,
46
69
  '```',
47
- ...(config.embeddings
48
- ? []
49
- : [
50
- '',
51
- `${config.label} has no embeddings API, so the knowledge base needs a`,
52
- 'second provider. Leave `EMBEDDINGS_MODEL` and `VECTOR_SIZE` alone and',
53
- 'add one (OpenAI, Scaleway or Cohere) before uploading documents.',
54
- ]),
55
70
  '',
71
+ 'Then `docker compose restart litellm`.',
72
+ '',
73
+ '</details>',
74
+ ...(config.embeddings ? [] : secondProviderForEmbeddings(config.label)),
75
+ '',
76
+ ];
77
+ }
78
+ /**
79
+ * What to add when the chosen provider serves chat and nothing else.
80
+ *
81
+ * Concrete rather than "add one (OpenAI, Scaleway or Cohere)", because the
82
+ * instructions above replace the whole `routes:` block — so the shipped
83
+ * `EMBEDDINGS_MODEL` default stops being routed at all, and the knowledge base
84
+ * fails on the first upload with a model id nothing serves. Telling someone to
85
+ * leave that variable alone was correct while a proxy served it and is wrong
86
+ * now.
87
+ *
88
+ * OpenAI rather than a choice, for the same reason the wizard picks defaults:
89
+ * one working recipe beats three that each need a decision. Derived from
90
+ * `LLM_PROVIDERS.openai` so the model name and its vector size cannot drift
91
+ * from what the wizard would have written.
92
+ */
93
+ function secondProviderForEmbeddings(label) {
94
+ const openai = llm_provider_1.LLM_PROVIDERS.openai;
95
+ const embeddings = openai.embeddings;
96
+ if (!embeddings) {
97
+ return [];
98
+ }
99
+ return [
100
+ '',
101
+ `${label} publishes no embeddings API, so the knowledge base needs a`,
102
+ 'second provider. Anything else with one will do; this is the shortest',
103
+ 'working version.',
104
+ '',
105
+ 'Add to `.env.local`:',
106
+ '',
107
+ '```',
108
+ `${openai.apiKeyEnvVar}=<your ${openai.label} key>`,
109
+ `EMBEDDINGS_MODEL=${embeddings.modelName}`,
110
+ `VECTOR_SIZE=${embeddings.vectorSize}`,
111
+ '```',
112
+ '',
113
+ 'And a second entry under `routes:`, beside the chat one above:',
114
+ '',
115
+ '```yaml',
116
+ ` ${embeddings.modelName}:`,
117
+ ` provider: ${openai.gatewayProvider}`,
118
+ ` model: ${embeddings.upstreamModel}`,
119
+ '```',
120
+ '',
121
+ 'Without both, uploads fail on a model id nothing serves — the route table',
122
+ 'you wrote above replaced the one that used to carry a default.',
56
123
  ];
57
124
  }
58
125
  function manualLlmSetupInstructions() {
@@ -63,11 +130,9 @@ function manualLlmSetupInstructions() {
63
130
  'base will not work until one is configured. Nothing here needs to go',
64
131
  'through a CLI — edit the two files below yourself.',
65
132
  '',
66
- 'Pick one provider, apply both edits, then restart the proxy:',
67
- '',
68
- '```bash',
69
- 'docker compose restart litellm',
70
- '```',
133
+ 'Ragen calls providers directly by default, so the two files are your',
134
+ '`.env.local` and the route table. Pick one provider, apply both edits,',
135
+ 'and restart the apps.',
71
136
  '',
72
137
  ...providerSection('openai'),
73
138
  ...providerSection('anthropic'),
@@ -80,11 +145,15 @@ function manualLlmSetupInstructions() {
80
145
  '',
81
146
  '## Check it worked',
82
147
  '',
148
+ 'One real call per model this installation is configured to use:',
149
+ '',
83
150
  '```bash',
84
- 'curl -s -H "Authorization: Bearer $LITELLM_MASTER_KEY" \\',
85
- ' http://localhost:4000/v1/models',
151
+ 'npm run gateway:preflight -- --probe',
86
152
  '```',
87
153
  '',
154
+ 'It resolves each model and calls it. "Configured" and "works" are',
155
+ 'different questions, and only the second one matters here.',
156
+ '',
88
157
  `Anything else — S3 storage, encryption at rest, Stripe, email, MCP`,
89
158
  `connectors — is documented at ${SELF_HOSTING_DOCS}.`,
90
159
  '',
@@ -1 +1 @@
1
- {"version":3,"file":"manual-setup.js","sourceRoot":"","sources":["../src/manual-setup.ts"],"names":[],"mappings":";;AAsEA,gEAkCC;AAxGD,iDAAuE;AAEvE;;;;;;;;GAQG;AAEH,MAAM,iBAAiB,GAAG,yCAAyC,CAAC;AAEpE,SAAS,eAAe,CAAC,MAAyB;IAChD,MAAM,MAAM,GAAG,4BAAa,CAAC,MAAM,CAAC,CAAC;IAErC,MAAM,QAAQ,GAAG;QACf,GAAG,MAAM,CAAC,YAAY,UAAU,MAAM,CAAC,KAAK,OAAO;QACnD,gCAAgC;QAChC,iBAAiB,MAAM,CAAC,SAAS,EAAE;QACnC,kBAAkB,MAAM,CAAC,SAAS,EAAE;KACrC,CAAC;IAEF,MAAM,SAAS,GAAG;QAChB,mBAAmB,MAAM,CAAC,SAAS,EAAE;QACrC,qBAAqB;QACrB,gBAAgB,MAAM,CAAC,YAAY,EAAE;QACrC,6BAA6B,MAAM,CAAC,YAAY,EAAE;KACnD,CAAC;IAEF,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,QAAQ,CAAC,IAAI,CACX,oBAAoB,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,EACjD,eAAe,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAC9C,CAAC;QACF,SAAS,CAAC,IAAI,CACZ,mBAAmB,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,EAChD,qBAAqB,EACrB,gBAAgB,MAAM,CAAC,UAAU,CAAC,YAAY,EAAE,EAChD,6BAA6B,MAAM,CAAC,YAAY,EAAE,CACnD,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,MAAM,CAAC,KAAK,EAAE;QACrB,EAAE;QACF,iCAAiC;QACjC,EAAE;QACF,KAAK;QACL,GAAG,QAAQ;QACX,KAAK;QACL,EAAE;QACF,oEAAoE;QACpE,EAAE;QACF,SAAS;QACT,GAAG,SAAS;QACZ,KAAK;QACL,GAAG,CAAC,MAAM,CAAC,UAAU;YACnB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,EAAE;gBACF,GAAG,MAAM,CAAC,KAAK,uDAAuD;gBACtE,uEAAuE;gBACvE,kEAAkE;aACnE,CAAC;QACN,EAAE;KACH,CAAC;AACJ,CAAC;AAED,SAAgB,0BAA0B;IACxC,OAAO;QACL,0BAA0B;QAC1B,EAAE;QACF,sEAAsE;QACtE,sEAAsE;QACtE,oDAAoD;QACpD,EAAE;QACF,8DAA8D;QAC9D,EAAE;QACF,SAAS;QACT,gCAAgC;QAChC,KAAK;QACL,EAAE;QACF,GAAG,eAAe,CAAC,QAAQ,CAAC;QAC5B,GAAG,eAAe,CAAC,WAAW,CAAC;QAC/B,+BAA+B;QAC/B,EAAE;QACF,mEAAmE;QACnE,yEAAyE;QACzE,qEAAqE;QACrE,yBAAyB;QACzB,EAAE;QACF,oBAAoB;QACpB,EAAE;QACF,SAAS;QACT,2DAA2D;QAC3D,mCAAmC;QACnC,KAAK;QACL,EAAE;QACF,oEAAoE;QACpE,iCAAiC,iBAAiB,GAAG;QACrD,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"manual-setup.js","sourceRoot":"","sources":["../src/manual-setup.ts"],"names":[],"mappings":"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"}