@ljoukov/llm 2.1.0 → 3.0.1

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/README.md CHANGED
@@ -9,7 +9,8 @@ Unified TypeScript wrapper over:
9
9
 
10
10
  - **OpenAI Responses API** (`openai`)
11
11
  - **Google Gemini via Vertex AI** (`@google/genai`)
12
- - **ChatGPT subscription models** via `chatgpt-*` model ids (requires `CHATGPT_AUTH_JSON_B64`)
12
+ - **Fireworks chat-completions models** (`kimi-k2.5`, `glm-5`, `minimax-m2.1`)
13
+ - **ChatGPT subscription models** via `chatgpt-*` model ids (reuses Codex auth store, or a token provider)
13
14
 
14
15
  Designed around a single streaming API that yields:
15
16
 
@@ -69,12 +70,36 @@ If deploying to Cloudflare Workers/Pages:
69
70
  jq -c . < path/to/service-account.json | wrangler secret put GOOGLE_SERVICE_ACCOUNT_JSON
70
71
  ```
71
72
 
73
+ ### Fireworks
74
+
75
+ - `FIREWORKS_TOKEN` (or `FIREWORKS_API_KEY`)
76
+
72
77
  ### ChatGPT subscription models
73
78
 
74
- - `CHATGPT_AUTH_JSON_B64`
79
+ By default, `chatgpt-*` models reuse the ChatGPT OAuth tokens stored by the Codex CLI:
80
+
81
+ - `${CODEX_HOME:-~/.codex}/auth.json`
82
+
83
+ If you deploy to multiple environments (Vercel, GCP, local dev, etc.), use a centralized HTTPS token provider that owns
84
+ refresh-token rotation and serves short-lived access tokens.
85
+
86
+ - `CHATGPT_AUTH_TOKEN_PROVIDER_URL` (example: `https://chatgpt-auth.<your-domain>`)
87
+ - `CHATGPT_AUTH_API_KEY` (shared secret; sent as `Authorization: Bearer ...` and `x-chatgpt-auth: ...`)
88
+ - `CHATGPT_AUTH_TOKEN_PROVIDER_STORE` (`kv` or `d1`, defaults to `kv`)
89
+
90
+ This repo includes a Cloudflare Workers token provider implementation in `chatgpt-auth/worker/`.
91
+
92
+ To seed the worker with a fresh OAuth token set via browser login:
93
+
94
+ ```bash
95
+ npm run chatgpt-auth:seed -- --worker-url https://chatgpt-auth.<your-domain>
96
+ ```
75
97
 
76
- This is a base64url-encoded JSON blob containing the ChatGPT OAuth tokens + account id (RFC 4648):
77
- https://www.rfc-editor.org/rfc/rfc4648
98
+ The CLI opens `auth.openai.com`, captures the localhost OAuth callback, exchanges the code, calls `POST /v1/seed`,
99
+ then resolves a smoke model from `GET /backend-api/codex/models` and runs a post-seed inference check (disable with `--skip-smoke-check`).
100
+
101
+ If `CHATGPT_AUTH_TOKEN_PROVIDER_URL` + `CHATGPT_AUTH_API_KEY` are set, `chatgpt-*` models will fetch tokens from the
102
+ token provider and will not read the local Codex auth store.
78
103
 
79
104
  ## Usage
80
105
 
@@ -245,6 +270,21 @@ const result = await generateText({
245
270
  console.log(result.text);
246
271
  ```
247
272
 
273
+ ### Fireworks
274
+
275
+ Use Fireworks model ids directly (for example `kimi-k2.5`, `glm-5`, `minimax-m2.1`):
276
+
277
+ ```ts
278
+ import { generateText } from "@ljoukov/llm";
279
+
280
+ const result = await generateText({
281
+ model: "kimi-k2.5",
282
+ input: "Return exactly: OK",
283
+ });
284
+
285
+ console.log(result.text);
286
+ ```
287
+
248
288
  ### ChatGPT subscription models
249
289
 
250
290
  Use a `chatgpt-` prefix:
@@ -348,14 +388,21 @@ const { value } = await generateJson({
348
388
 
349
389
  ## Tools
350
390
 
351
- This library supports two kinds of tools:
391
+ There are three tool-enabled call patterns:
392
+
393
+ 1. `generateText()` for provider-native/server-side tools (for example web search).
394
+ 2. `runToolLoop()` for your runtime JS/TS tools (function tools executed in your process).
395
+ 3. `runAgentLoop()` for filesystem tasks (a convenience wrapper around `runToolLoop()`).
352
396
 
353
- - Model tools (server-side): `web-search` and `code-execution`
354
- - Your tools (JS/TS code): use `runToolLoop()` and `tool()`
397
+ Architecture note:
355
398
 
356
- ### Model tools (web search / code execution)
399
+ - Filesystem tools are not a separate execution system.
400
+ - `runAgentLoop()` constructs a filesystem toolset, merges your optional custom tools, then calls the same `runToolLoop()` engine.
401
+ - This behavior is model-agnostic at API level; profile selection only adapts tool shape for model compatibility.
357
402
 
358
- These tools run on the provider side.
403
+ ### Provider-Native Tools (`generateText()`)
404
+
405
+ Use this when the model provider executes the tool remotely (for example search/code-exec style tools).
359
406
 
360
407
  ```ts
361
408
  import { generateText } from "@ljoukov/llm";
@@ -369,9 +416,9 @@ const result = await generateText({
369
416
  console.log(result.text);
370
417
  ```
371
418
 
372
- ### Your tools (function calling)
419
+ ### Runtime Tools (`runToolLoop()`)
373
420
 
374
- `runToolLoop()` runs a simple function-calling loop until the model returns a final answer or the step limit is hit.
421
+ Use this when the model should call your local runtime functions.
375
422
 
376
423
  ```ts
377
424
  import { runToolLoop, tool } from "@ljoukov/llm";
@@ -392,47 +439,24 @@ const result = await runToolLoop({
392
439
  console.log(result.text);
393
440
  ```
394
441
 
395
- ### Built-in `apply_patch` tool
396
-
397
- The library includes a Codex-style `apply_patch` tool with a pluggable filesystem adapter.
398
-
399
- ```ts
400
- import {
401
- createApplyPatchTool,
402
- createInMemoryAgentFilesystem,
403
- runToolLoop,
404
- } from "@ljoukov/llm";
442
+ Use `customTool()` only when you need freeform/non-JSON tool input grammar.
405
443
 
406
- const fs = createInMemoryAgentFilesystem({
407
- "/repo/index.ts": "export const value = 1;\n",
408
- });
444
+ ### Filesystem Tasks (`runAgentLoop()`)
409
445
 
410
- const result = await runToolLoop({
411
- model: "chatgpt-gpt-5.3-codex",
412
- input: "Use apply_patch to change value from 1 to 2.",
413
- tools: {
414
- apply_patch: createApplyPatchTool({
415
- cwd: "/repo",
416
- fs,
417
- checkAccess: ({ path }) => {
418
- if (!path.startsWith("/repo/")) {
419
- throw new Error("Writes are allowed only inside /repo");
420
- }
421
- },
422
- }),
423
- },
424
- });
446
+ Use this for read/search/write tasks in a workspace. The library auto-selects filesystem tool profile by model when `profile: "auto"`:
425
447
 
426
- console.log(result.text);
427
- ```
448
+ - Codex-like models: Codex-compatible filesystem tool shape.
449
+ - Gemini models: Gemini-compatible filesystem tool shape.
450
+ - Other models: model-agnostic profile (currently Gemini-style).
428
451
 
429
- ### `runAgentLoop()` with model-aware filesystem tools
452
+ Confinement/policy is set through `filesystemTool.options`:
430
453
 
431
- Use `runAgentLoop()` when you want a default filesystem toolset chosen by model:
454
+ - `cwd`: workspace root for path resolution.
455
+ - `fs`: backend (`createNodeAgentFilesystem()` or `createInMemoryAgentFilesystem()`).
456
+ - `checkAccess`: hook for allow/deny policy + audit.
457
+ - `allowOutsideCwd`: opt-out confinement (default is false).
432
458
 
433
- - Codex-like models -> `apply_patch`, `read_file`, `list_dir`, `grep_files`
434
- - Gemini models -> `read_file`, `write_file`, `replace`, `list_directory`, `grep_search`, `glob`
435
- - Other models -> model-agnostic (Gemini-style) set by default
459
+ Detailed reference: `docs/agent-filesystem-tools.md`.
436
460
 
437
461
  ```ts
438
462
  import { createInMemoryAgentFilesystem, runAgentLoop } from "@ljoukov/llm";
@@ -456,14 +480,42 @@ const result = await runAgentLoop({
456
480
  console.log(result.text);
457
481
  ```
458
482
 
459
- ## Agent benchmark (micro)
483
+ If you need exact control over tool definitions, build the filesystem toolset yourself and call `runToolLoop()` directly.
460
484
 
461
- For small edit-harness experiments with `chatgpt-gpt-5.3-codex`:
485
+ ```ts
486
+ import {
487
+ createFilesystemToolSetForModel,
488
+ createInMemoryAgentFilesystem,
489
+ runToolLoop,
490
+ } from "@ljoukov/llm";
491
+
492
+ const fs = createInMemoryAgentFilesystem({ "/repo/a.ts": "export const n = 1;\n" });
493
+ const tools = createFilesystemToolSetForModel("chatgpt-gpt-5.3-codex", {
494
+ cwd: "/repo",
495
+ fs,
496
+ });
497
+
498
+ const result = await runToolLoop({
499
+ model: "chatgpt-gpt-5.3-codex",
500
+ input: "Update n to 2.",
501
+ tools,
502
+ });
503
+ ```
504
+
505
+ ## Agent benchmark (filesystem extraction)
506
+
507
+ For filesystem extraction/summarization evaluation across Codex, Fireworks, and Gemini models:
462
508
 
463
509
  ```bash
464
510
  npm run bench:agent
465
511
  ```
466
512
 
513
+ Standard full refresh (all tasks, auto-write `LATEST_RESULTS.md`, refresh `traces/latest`, prune old traces):
514
+
515
+ ```bash
516
+ npm run bench:agent:latest
517
+ ```
518
+
467
519
  Estimate-only:
468
520
 
469
521
  ```bash