create-nola-lang 0.1.10 → 0.1.11
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/dist/{chunk-G2TOUJVB.js → chunk-MAULRZZD.js} +17 -6
- package/dist/flow.js +1 -1
- package/dist/index.js +1 -1
- package/dist/main.js +1 -1
- package/dist/providers.js +1 -1
- package/dist/scaffold.d.ts +6 -0
- package/dist/scaffold.js +20 -3
- package/dist/trial.d.ts +1 -1
- package/dist/trial.js +2 -2
- package/package.json +1 -1
- package/skills/nola/SKILL.md +1 -1
- package/skills/nola/references/config.md +32 -19
- package/skills/nola/references/syntax.md +1 -1
- package/templates/_gitignore +10 -0
- package/templates/_providers/nola.config.ts +2 -2
- package/templates/starter/nola.config.ts +2 -0
- package/templates/empty/_gitignore +0 -5
- package/templates/starter/_gitignore +0 -5
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
|
|
6
6
|
// src/providers.ts
|
|
7
7
|
var PROVIDERS = [
|
|
8
|
-
{ id: "nola", label: "Nola", hint: "25 free runs, no account or provider key needed", model: "nola
|
|
8
|
+
{ id: "nola", label: "Nola", hint: "25 free runs, no account or provider key needed", model: '"nola"' },
|
|
9
9
|
{ id: "openai", label: "OpenAI", hint: 'openai("gpt-5-mini"), reads OPENAI_API_KEY', envVar: "OPENAI_API_KEY", model: 'openai("gpt-5-mini")' },
|
|
10
10
|
{
|
|
11
11
|
id: "anthropic",
|
|
@@ -176,6 +176,11 @@ function providerConfigUrl(provider) {
|
|
|
176
176
|
return new URL(`../templates/_providers/${provider}.config.ts`, import.meta.url);
|
|
177
177
|
}
|
|
178
178
|
var RENAMES = { _gitignore: ".gitignore" };
|
|
179
|
+
var GITIGNORE_URL = new URL("../templates/_gitignore", import.meta.url);
|
|
180
|
+
async function withRecommendedGitignore(files) {
|
|
181
|
+
if (!files.has(".gitignore")) files.set(".gitignore", await readFile3(GITIGNORE_URL, "utf8"));
|
|
182
|
+
return files;
|
|
183
|
+
}
|
|
179
184
|
var SUBSTITUTED = /* @__PURE__ */ new Set(["package.json", "README.md", "main.ts"]);
|
|
180
185
|
function nextStepsComment(ide, template) {
|
|
181
186
|
if (ide === "vscode") {
|
|
@@ -198,11 +203,11 @@ var OFFLINE_ONLY = /* @__PURE__ */ new Set(["nola.replay.jsonl"]);
|
|
|
198
203
|
var README_NOTES = {
|
|
199
204
|
offline: {
|
|
200
205
|
START_NOTE: "works offline, no API key needed",
|
|
201
|
-
PROVIDER_NOTE:
|
|
206
|
+
PROVIDER_NOTE: 'The starter runs offline: `nola.config.ts` replays answers from the committed\n`nola.replay.jsonl` ledger. The ledger is keyed by the exact prompt, so once\nyou edit `src/person.tsi` or add your own asks, switch the config to a real\nmodel (see the comment in `nola.config.ts`): `model: "nola"` with a key from\n`npx nola-lang key` (25 free runs), or your own provider and its key.'
|
|
202
207
|
},
|
|
203
208
|
nola: {
|
|
204
209
|
START_NOTE: "uses your 25 free Nola runs (key in .env)",
|
|
205
|
-
PROVIDER_NOTE:
|
|
210
|
+
PROVIDER_NOTE: '`nola.config.ts` sets `model: "nola"` \u2014 platform-served inference with the trial key the\nscaffold wrote to `.env` (git-ignored). Out of runs? `npx nola-lang account` opens\nyour Nola account, where prepaid balance is added, or bring your\nown model (see the comment in `nola.config.ts`).'
|
|
206
211
|
}
|
|
207
212
|
};
|
|
208
213
|
function readmeNotes(provider) {
|
|
@@ -239,7 +244,9 @@ async function scaffold(targetDir, opts = {}) {
|
|
|
239
244
|
const version = await ownVersion();
|
|
240
245
|
if (def.source === "example") {
|
|
241
246
|
const dev = await devExamplesDir();
|
|
242
|
-
const exampleFiles =
|
|
247
|
+
const exampleFiles = await withRecommendedGitignore(
|
|
248
|
+
dev ? await collectExampleFromDisk(dev, template) : await fetchExampleFromGitHub(template, version)
|
|
249
|
+
);
|
|
243
250
|
const manifest = exampleFiles.get("package.json");
|
|
244
251
|
if (manifest) exampleFiles.set("package.json", rewriteExamplePackageJson(manifest, { name, version }));
|
|
245
252
|
for (const [relPath, content] of exampleFiles) {
|
|
@@ -276,6 +283,10 @@ async function scaffold(targetDir, opts = {}) {
|
|
|
276
283
|
}
|
|
277
284
|
};
|
|
278
285
|
await copyDir(".", ".");
|
|
286
|
+
if (!files.includes(".gitignore")) {
|
|
287
|
+
await writeFile(join3(absRoot, ".gitignore"), await readFile3(GITIGNORE_URL, "utf8"));
|
|
288
|
+
files.push(".gitignore");
|
|
289
|
+
}
|
|
279
290
|
return { root, files: files.sort() };
|
|
280
291
|
}
|
|
281
292
|
|
|
@@ -1286,7 +1297,7 @@ async function applyTrial(dir, init) {
|
|
|
1286
1297
|
const { wrote, skipped } = await writeEnvKey(root, init.apiKey);
|
|
1287
1298
|
wrote.push(...await ensureEnvIgnored(root));
|
|
1288
1299
|
if (init.hasConfig) {
|
|
1289
|
-
skipped.push(
|
|
1300
|
+
skipped.push('nola.config.ts already exists \u2014 set `model: "nola"` to use the trial key');
|
|
1290
1301
|
} else {
|
|
1291
1302
|
await writeFile7(join9(root, "nola.config.ts"), await readFile8(TRIAL_CONFIG_URL, "utf8"));
|
|
1292
1303
|
wrote.push("nola.config.ts");
|
|
@@ -1757,7 +1768,7 @@ function trialFailureNote(err) {
|
|
|
1757
1768
|
reason = `too many trials from this network${wait} (${err.message})`;
|
|
1758
1769
|
}
|
|
1759
1770
|
return `Could not get a Nola API key: ${reason}
|
|
1760
|
-
The project uses its default provider instead. Retry later with \`npx nola-lang key\`, then set \`model: nola
|
|
1771
|
+
The project uses its default provider instead. Retry later with \`npx nola-lang key\`, then set \`model: "nola"\` in nola.config.ts.`;
|
|
1761
1772
|
}
|
|
1762
1773
|
async function obtainTrial(prompter, opts, interactive) {
|
|
1763
1774
|
try {
|
package/dist/flow.js
CHANGED
|
@@ -428,7 +428,7 @@ function trialFailureNote(err) {
|
|
|
428
428
|
const wait = err.retryAfterMs !== undefined && err.retryAfterMs > 0 ? ` — try again in ${formatWait(err.retryAfterMs)}` : "";
|
|
429
429
|
reason = `too many trials from this network${wait} (${err.message})`;
|
|
430
430
|
}
|
|
431
|
-
return `Could not get a Nola API key: ${reason}\nThe project uses its default provider instead. Retry later with \`npx nola-lang key\`, then set \`model: nola
|
|
431
|
+
return `Could not get a Nola API key: ${reason}\nThe project uses its default provider instead. Retry later with \`npx nola-lang key\`, then set \`model: "nola"\` in nola.config.ts.`;
|
|
432
432
|
}
|
|
433
433
|
/**
|
|
434
434
|
* `acquireKey` for the scaffold: a failure is a note, never an exit code (the
|
package/dist/index.js
CHANGED
package/dist/main.js
CHANGED
package/dist/providers.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const PROVIDERS = [
|
|
2
|
-
{ id: "nola", label: "Nola", hint: "25 free runs, no account or provider key needed", model: "nola
|
|
2
|
+
{ id: "nola", label: "Nola", hint: "25 free runs, no account or provider key needed", model: '"nola"' },
|
|
3
3
|
{ id: "openai", label: "OpenAI", hint: 'openai("gpt-5-mini"), reads OPENAI_API_KEY', envVar: "OPENAI_API_KEY", model: 'openai("gpt-5-mini")' },
|
|
4
4
|
{
|
|
5
5
|
id: "anthropic",
|
package/dist/scaffold.d.ts
CHANGED
|
@@ -28,6 +28,12 @@ export interface ScaffoldOptions {
|
|
|
28
28
|
}
|
|
29
29
|
/** The config a live provider choice writes over the template's own (`templates/_providers/<id>.config.ts`). */
|
|
30
30
|
export declare function providerConfigUrl(provider: Exclude<ProviderId, "none">): URL;
|
|
31
|
+
/**
|
|
32
|
+
* Add the recommended `.gitignore` to an example's files. Examples are copied
|
|
33
|
+
* verbatim from `examples/`, where the monorepo's root ignore file covers them,
|
|
34
|
+
* so they carry none — one an example does carry wins.
|
|
35
|
+
*/
|
|
36
|
+
export declare function withRecommendedGitignore(files: Map<string, string>): Promise<Map<string, string>>;
|
|
31
37
|
/**
|
|
32
38
|
* The comment that opens src/main.ts — the file the scaffold lands the user
|
|
33
39
|
* on (VS Code opens it as the active editor), so it carries the first three
|
package/dist/scaffold.js
CHANGED
|
@@ -13,6 +13,18 @@ export function providerConfigUrl(provider) {
|
|
|
13
13
|
}
|
|
14
14
|
/** _gitignore ships underscored (npm pack strips nested .gitignore files). */
|
|
15
15
|
const RENAMES = { _gitignore: ".gitignore" };
|
|
16
|
+
/** The ONE recommended .gitignore — every scaffold gets it; no template keeps a copy of its own. */
|
|
17
|
+
const GITIGNORE_URL = new URL("../templates/_gitignore", import.meta.url);
|
|
18
|
+
/**
|
|
19
|
+
* Add the recommended `.gitignore` to an example's files. Examples are copied
|
|
20
|
+
* verbatim from `examples/`, where the monorepo's root ignore file covers them,
|
|
21
|
+
* so they carry none — one an example does carry wins.
|
|
22
|
+
*/
|
|
23
|
+
export async function withRecommendedGitignore(files) {
|
|
24
|
+
if (!files.has(".gitignore"))
|
|
25
|
+
files.set(".gitignore", await readFile(GITIGNORE_URL, "utf8"));
|
|
26
|
+
return files;
|
|
27
|
+
}
|
|
16
28
|
/** Files whose __NAME__/__VERSION__, README-note and __NEXT_STEPS__ placeholders are substituted. */
|
|
17
29
|
const SUBSTITUTED = new Set(["package.json", "README.md", "main.ts"]);
|
|
18
30
|
/**
|
|
@@ -46,11 +58,12 @@ const README_NOTES = {
|
|
|
46
58
|
PROVIDER_NOTE: "The starter runs offline: `nola.config.ts` replays answers from the committed\n" +
|
|
47
59
|
"`nola.replay.jsonl` ledger. The ledger is keyed by the exact prompt, so once\n" +
|
|
48
60
|
"you edit `src/person.tsi` or add your own asks, switch the config to a real\n" +
|
|
49
|
-
"model (see the comment in `nola.config.ts`)
|
|
61
|
+
"model (see the comment in `nola.config.ts`): `model: \"nola\"` with a key from\n" +
|
|
62
|
+
"`npx nola-lang key` (25 free runs), or your own provider and its key.",
|
|
50
63
|
},
|
|
51
64
|
nola: {
|
|
52
65
|
START_NOTE: "uses your 25 free Nola runs (key in .env)",
|
|
53
|
-
PROVIDER_NOTE: "`nola.config.ts` sets `model: nola
|
|
66
|
+
PROVIDER_NOTE: "`nola.config.ts` sets `model: \"nola\"` — platform-served inference with the trial key the\n" +
|
|
54
67
|
"scaffold wrote to `.env` (git-ignored). Out of runs? `npx nola-lang account` opens\n" +
|
|
55
68
|
"your Nola account, where prepaid balance is added, or bring your\n" +
|
|
56
69
|
"own model (see the comment in `nola.config.ts`).",
|
|
@@ -104,7 +117,7 @@ export async function scaffold(targetDir, opts = {}) {
|
|
|
104
117
|
const version = await ownVersion();
|
|
105
118
|
if (def.source === "example") {
|
|
106
119
|
const dev = await devExamplesDir();
|
|
107
|
-
const exampleFiles = dev ? await collectExampleFromDisk(dev, template) : await fetchExampleFromGitHub(template, version);
|
|
120
|
+
const exampleFiles = await withRecommendedGitignore(dev ? await collectExampleFromDisk(dev, template) : await fetchExampleFromGitHub(template, version));
|
|
108
121
|
const manifest = exampleFiles.get("package.json");
|
|
109
122
|
if (manifest)
|
|
110
123
|
exampleFiles.set("package.json", rewriteExamplePackageJson(manifest, { name, version }));
|
|
@@ -151,6 +164,10 @@ export async function scaffold(targetDir, opts = {}) {
|
|
|
151
164
|
}
|
|
152
165
|
};
|
|
153
166
|
await copyDir(".", ".");
|
|
167
|
+
if (!files.includes(".gitignore")) {
|
|
168
|
+
await writeFile(join(absRoot, ".gitignore"), await readFile(GITIGNORE_URL, "utf8"));
|
|
169
|
+
files.push(".gitignore");
|
|
170
|
+
}
|
|
154
171
|
return { root, files: files.sort() };
|
|
155
172
|
}
|
|
156
173
|
//# sourceMappingURL=scaffold.js.map
|
package/dist/trial.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** The canonical `model: nola
|
|
1
|
+
/** The canonical `model: "nola"` config every template gets when Nola is the chosen provider. */
|
|
2
2
|
export declare const TRIAL_CONFIG_URL: import("url").URL;
|
|
3
3
|
export declare const ENV_KEY = "NOLA_API_KEY";
|
|
4
4
|
export interface TrialApplyResult {
|
package/dist/trial.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { appendFile, readFile, writeFile } from "node:fs/promises";
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
|
-
/** The canonical `model: nola
|
|
4
|
+
/** The canonical `model: "nola"` config every template gets when Nola is the chosen provider. */
|
|
5
5
|
export const TRIAL_CONFIG_URL = new URL("../templates/_providers/nola.config.ts", import.meta.url);
|
|
6
6
|
export const ENV_KEY = "NOLA_API_KEY";
|
|
7
7
|
const IGNORE_LINES = [".env", ".env.*"];
|
|
@@ -79,7 +79,7 @@ export async function applyTrial(dir, init) {
|
|
|
79
79
|
const { wrote, skipped } = await writeEnvKey(root, init.apiKey);
|
|
80
80
|
wrote.push(...(await ensureEnvIgnored(root)));
|
|
81
81
|
if (init.hasConfig) {
|
|
82
|
-
skipped.push('nola.config.ts already exists — set `model: nola
|
|
82
|
+
skipped.push('nola.config.ts already exists — set `model: "nola"` to use the trial key');
|
|
83
83
|
}
|
|
84
84
|
else {
|
|
85
85
|
await writeFile(join(root, "nola.config.ts"), await readFile(TRIAL_CONFIG_URL, "utf8"));
|
package/package.json
CHANGED
package/skills/nola/SKILL.md
CHANGED
|
@@ -43,7 +43,7 @@ infer function extractPerson(.text: string) {
|
|
|
43
43
|
instruction text.
|
|
44
44
|
- `ask with <modelName> <intent>` — routes one ask through a named model
|
|
45
45
|
from `nola.config.ts`. The name must be a static identifier. When the
|
|
46
|
-
platform serves inference (`model: nola
|
|
46
|
+
platform serves inference (`model: "nola"`) any unconfigured
|
|
47
47
|
name is legal — it is sent to the platform as a free-form inference profile.
|
|
48
48
|
- Prompt templates: inside ANY instruction backticks (marker, extractor,
|
|
49
49
|
call hint) a hole that starts with a single dot — `${.member}` — reads
|
|
@@ -7,8 +7,9 @@ import { defineConfig, nola, terminalTrace } from "@nola-lang/runtime";
|
|
|
7
7
|
import { openai, mockProvider, withRetry } from "@nola-lang/providers";
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
-
`defineConfig`, the `nola` namespace (`nola.infer()`, `nola.tracer()`
|
|
11
|
-
|
|
10
|
+
`defineConfig`, the `nola` namespace (`nola.infer()`, `nola.tracer()` —
|
|
11
|
+
import it ONLY when you need their options; the plain cases are the strings
|
|
12
|
+
`model: "nola"` and `telemetry: "<url>"`), `terminalTrace()` and everything app-facing come from `@nola-lang/runtime`.
|
|
12
13
|
Everything bring-your-own — vendor factories (`openai`, `anthropic`,
|
|
13
14
|
`google`, `typesafe`, `mockProvider`), resilience combinators (`withRetry`, `fallback`,
|
|
14
15
|
`roundRobin`, `constant`, `exponential`) and record/replay (`record`,
|
|
@@ -48,15 +49,22 @@ fails definitively before the network on anything else. Use it behind
|
|
|
48
49
|
escalate to a general model. Never scaffold it as the only model.
|
|
49
50
|
|
|
50
51
|
`nola` is a NAMESPACE, not a function (`nola({})` is a type error).
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
The platform model is written as the STRING `"nola"` — the Nola platform
|
|
53
|
+
(api.nola.sh) serves inference, reads `NOLA_API_KEY`, and picks the model.
|
|
54
|
+
PREFER this form; it is what the scaffolder writes and it needs no `nola`
|
|
55
|
+
import:
|
|
54
56
|
|
|
55
57
|
```ts
|
|
56
|
-
import { defineConfig
|
|
57
|
-
export default defineConfig({ model: nola
|
|
58
|
+
import { defineConfig } from "@nola-lang/runtime";
|
|
59
|
+
export default defineConfig({ model: "nola" });
|
|
58
60
|
```
|
|
59
61
|
|
|
62
|
+
`"nola"` is short for `nola.infer()`. It is the ONLY string the `model` slot
|
|
63
|
+
takes (any other string is NOLA3003 — `model: "gpt-5"` is not a thing) and
|
|
64
|
+
it works as the map's `default` too. Write the `nola.infer(...)` call only
|
|
65
|
+
when you need an argument — the upstream selector or the connection options
|
|
66
|
+
(a self-hosted console at `baseUrl`, a key source, `retry`).
|
|
67
|
+
|
|
60
68
|
When the platform serves, `ask with <name>` accepts ANY name — a configured
|
|
61
69
|
map key pins that model as usual, and any other name (`fast`, `careful`, …)
|
|
62
70
|
is sent with the request as a free-form inference profile that the
|
|
@@ -65,9 +73,9 @@ temperature/topK tuning). A local model map keeps strict name validation
|
|
|
65
73
|
(unknown names are NOLA3004). `nola.infer("<provider>/<model>")` names the
|
|
66
74
|
upstream explicitly; `nola.infer({ baseUrl, apiKey, apiKeyEnv, retry, model })`
|
|
67
75
|
carries the connection. Beside your own models it is the map's `default`:
|
|
68
|
-
`model: { default: nola
|
|
69
|
-
is implied — traces go to
|
|
70
|
-
`nola.tracer()
|
|
76
|
+
`model: { default: "nola", fast: openai("gpt-5-nano") }`. Nothing else
|
|
77
|
+
is implied — traces go to a Nola console only when `telemetry` lists its
|
|
78
|
+
URL (or `nola.tracer()`).
|
|
71
79
|
|
|
72
80
|
`npm create nola` asks *Select an inference provider:* right after the
|
|
73
81
|
template — Nola (25 free runs) first, then OpenAI / Anthropic / Gemini, then
|
|
@@ -114,7 +122,7 @@ export infer function summarize(.text: string) {
|
|
|
114
122
|
|
|
115
123
|
An `ask with` name that is not a key of the map fails at run time with
|
|
116
124
|
NOLA3004, listing the configured names — EXCEPT when `default` is
|
|
117
|
-
`nola
|
|
125
|
+
the platform model (`"nola"`), where the unmatched name becomes an inference profile for
|
|
118
126
|
the platform instead of an error.
|
|
119
127
|
|
|
120
128
|
### Other config sections
|
|
@@ -146,14 +154,19 @@ event at `debug`, coloured on a TTY, written to STDERR — stdout stays the
|
|
|
146
154
|
program's), ONE observer, or an ARRAY of
|
|
147
155
|
observers. An observer or an array REPLACES the terminal — nothing is
|
|
148
156
|
implied, so list `terminalTrace()` to keep it; `[]` is silent. Observers:
|
|
149
|
-
`
|
|
150
|
-
|
|
151
|
-
keyless on loopback; never gated —
|
|
157
|
+
an `http(s)` URL STRING — the tracer, PREFER this form (`telemetry:
|
|
158
|
+
"http://127.0.0.1:4141"`, or as an array entry; posts to a Nola-Protocol
|
|
159
|
+
server such as `npx nola-lang console`; keyless on loopback; never gated —
|
|
160
|
+
listed means sends; a single URL replaces the terminal like any single
|
|
161
|
+
observer, so write `["http://127.0.0.1:4141", terminalTrace()]` to keep
|
|
162
|
+
both; a non-URL string is NOLA3003), the call behind it for its options —
|
|
163
|
+
`nola.tracer()` (default target) / `nola.tracer({ baseUrl, apiKey? })` —
|
|
164
|
+
`terminalTrace({
|
|
152
165
|
level })`, or any object with on* methods (`onAskStart`,
|
|
153
166
|
`onProviderRequest`, `onProviderResponse`, `onValidationFailed`, `onRetry`,
|
|
154
167
|
`onAskEnd`, `onInvocationStart`, `onInvocationEnd`; that shape is
|
|
155
|
-
`NolaTelemetry`). The global `console` is NOT an entry. `nola
|
|
156
|
-
NOT imply a tracer. `NOLA_TRACING_URL` appends
|
|
168
|
+
`NolaTelemetry`). The global `console` is NOT an entry. `model: "nola"` does
|
|
169
|
+
NOT imply a tracer. `NOLA_TRACING_URL` appends that URL's tracer; a config
|
|
157
170
|
that lists a tracer itself wins, with a notice. Sending is fire-and-forget
|
|
158
171
|
and never affects inference. The platform model is root-only: it cannot
|
|
159
172
|
appear inside combinators or non-default map entries. Start the local
|
|
@@ -210,11 +223,11 @@ the providers package:
|
|
|
210
223
|
"check": "nola check"
|
|
211
224
|
},
|
|
212
225
|
"dependencies": {
|
|
213
|
-
"@nola-lang/providers": "^0.1.
|
|
214
|
-
"@nola-lang/runtime": "^0.1.
|
|
226
|
+
"@nola-lang/providers": "^0.1.11",
|
|
227
|
+
"@nola-lang/runtime": "^0.1.11"
|
|
215
228
|
},
|
|
216
229
|
"devDependencies": {
|
|
217
|
-
"nola-lang": "^0.1.
|
|
230
|
+
"nola-lang": "^0.1.11",
|
|
218
231
|
"typescript": "^5.6.0"
|
|
219
232
|
},
|
|
220
233
|
"engines": { "node": ">=22.18" }
|
|
@@ -201,7 +201,7 @@ export infer function summarize(.text: string) {
|
|
|
201
201
|
use `.withModel(...)` for a dynamic model.
|
|
202
202
|
- The name is matched against the config at ask time, not compile time. A
|
|
203
203
|
name that matches a `model` map key pins that model. When the platform
|
|
204
|
-
serves inference (`model: nola
|
|
204
|
+
serves inference (`model: "nola"`) an unmatched name is a
|
|
205
205
|
free-form inference profile sent to the platform — not an error; under a
|
|
206
206
|
local default an unknown name is a runtime `NolaConfigError` (NOLA3004).
|
|
207
207
|
- `ask without` is a plain ask of the identifier `without`, not a pin.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineConfig
|
|
1
|
+
import { defineConfig } from "@nola-lang/runtime";
|
|
2
2
|
|
|
3
3
|
// Nola serves inference: reads NOLA_API_KEY from .env (your free trial key)
|
|
4
4
|
// and picks the model. Out of runs? `npx nola-lang account` opens your Nola
|
|
@@ -7,5 +7,5 @@ import { defineConfig, nola } from "@nola-lang/runtime";
|
|
|
7
7
|
// import { openai } from "@nola-lang/providers";
|
|
8
8
|
// model: openai("gpt-5-mini"), // reads OPENAI_API_KEY
|
|
9
9
|
export default defineConfig({
|
|
10
|
-
model: nola
|
|
10
|
+
model: "nola",
|
|
11
11
|
});
|
|
@@ -6,6 +6,8 @@ export default defineConfig({
|
|
|
6
6
|
// (nola.replay.jsonl), so the first `npm start` needs no API key. The
|
|
7
7
|
// ledger is keyed by the exact prompt — once you edit the .tsi or add
|
|
8
8
|
// asks, switch to a real model:
|
|
9
|
+
// model: "nola", // Nola serves inference; `npx nola-lang key` writes NOLA_API_KEY (25 free runs)
|
|
10
|
+
// or bring your own:
|
|
9
11
|
// import { openai } from "@nola-lang/providers";
|
|
10
12
|
// model: openai("gpt-5-mini"), // reads OPENAI_API_KEY
|
|
11
13
|
model: replay("./nola.replay.jsonl"),
|