evalution 1.0.1 → 1.0.3

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.
@@ -8,7 +8,7 @@
8
8
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
9
9
  <title>Evalution</title>
10
10
  <link rel="icon" type="image/svg+xml" href="/favicon.svg">
11
- <script type="module" crossorigin src="/assets/index-CORbBplP.js"></script>
11
+ <script type="module" crossorigin src="/assets/index-DR7qdRRh.js"></script>
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-CgcFVsRZ.css">
13
13
  </head>
14
14
  <body>
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Tracer } from "@opentelemetry/api";
1
+ import { AttributeValue, Attributes, Tracer } from "@opentelemetry/api";
2
2
  import { SpanProcessor } from "@opentelemetry/sdk-trace-base";
3
3
  import { CalleeBinding, ExtractedProps, PropDefinition, PropDefinition as PropDefinition$1, PropValue, PropValue as PropValue$1, SourceSpan } from "ts-proppy";
4
4
  import { GoogleGenAI } from "@google/genai";
@@ -230,7 +230,7 @@ interface LLMSpanDetails {
230
230
  /** Dollar cost of the call, if known. */
231
231
  cost?: number;
232
232
  /** Model parameters (temperature, max_tokens, …). */
233
- parameters?: Record<string, unknown>;
233
+ modelParameters?: Record<string, unknown>;
234
234
  }
235
235
  /**
236
236
  * A span in a {@link Trace}. Spans form a tree via {@link parentId}.
@@ -438,14 +438,12 @@ interface PromptProvider<TPrompt extends NormalizedPrompt = NormalizedPrompt> {
438
438
  */
439
439
  updatePromptProperties?(promptId: string, updates: NormalizedPromptUpdates): Promise<TPrompt>;
440
440
  /**
441
- * Executes a prompt and returns either a result object (when `stream` is
442
- * `false`) or an async text iterable (when `stream` is `true`).
441
+ * Executes a prompt.
443
442
  *
444
443
  * @param promptId - ID of the prompt to run.
445
444
  * @param params - Positional arguments forwarded to the prompt function.
446
- * @param stream - When `true`, the return value is an async text iterator.
447
445
  */
448
- execute(promptId: string, params: any[], stream: boolean): Promise<any>;
446
+ execute(promptId: string, params: any[]): Promise<void>;
449
447
  /**
450
448
  * Returns the model catalog (known providers and popular models) for this
451
449
  * provider's underlying SDK.
@@ -496,6 +494,18 @@ interface PromptProvider<TPrompt extends NormalizedPrompt = NormalizedPrompt> {
496
494
  }
497
495
  //#endregion
498
496
  //#region src/trace/prompt-tracer.d.ts
497
+ interface PromptsHelperOptions {
498
+ /**
499
+ * Globally-unique identifier for this group of prompts.
500
+ */
501
+ readonly id: string;
502
+ }
503
+ type PromptsFactory<Args extends any[] = never[], Prompt = unknown> = (...args: Args) => Record<string, (...args: any[]) => Prompt>;
504
+ /**
505
+ * Intended to be used in the `satisfies` clause of a `prompts` export from an
506
+ * SDK adapter package.
507
+ */
508
+ type PromptsHelper = (opts: PromptsHelperOptions, factory: PromptsFactory<any[], any>) => PromptsFactory<any[], any>;
499
509
  /**
500
510
  * Attribute name a span can set to pick one of evalution's span-kind values
501
511
  * (`'LLM'`, `'TOOL'`, `'AGENT'`, `'EMBEDDING'`, `'DEFAULT'`). Falls back to
@@ -503,10 +513,9 @@ interface PromptProvider<TPrompt extends NormalizedPrompt = NormalizedPrompt> {
503
513
  */
504
514
  declare const SPAN_KIND_ATTRIBUTE = "evalution.span.type";
505
515
  /**
506
- * Attribute name a span can set to scope its {@link PROMPT_ID_ATTRIBUTE} to a
507
- * specific prompt provider. When absent, the prompt ID is treated as global.
516
+ * Attribute name a span can set to give a human-readable name to the prompt.
508
517
  */
509
- declare const PROMPT_PROVIDER_ID_ATTRIBUTE = "evalution.prompt.provider.id";
518
+ declare const PROMPT_NAME_ATTRIBUTE = "gen_ai.prompt.name";
510
519
  /**
511
520
  * Attribute name a span can set to link itself to a specific prompt. The value
512
521
  * is a globally-unique prompt ID unless {@link PROMPT_PROVIDER_ID_ATTRIBUTE} is
@@ -514,9 +523,21 @@ declare const PROMPT_PROVIDER_ID_ATTRIBUTE = "evalution.prompt.provider.id";
514
523
  */
515
524
  declare const PROMPT_ID_ATTRIBUTE = "evalution.prompt.id";
516
525
  /**
517
- * Attribute name a span can set to give a human-readable name to the prompt.
526
+ * Attribute name a span can set to scope its {@link PROMPT_ID_ATTRIBUTE} to a
527
+ * specific prompt provider. When absent, the prompt ID is treated as global.
518
528
  */
519
- declare const PROMPT_NAME_ATTRIBUTE = "gen_ai.prompt.name";
529
+ declare const PROMPT_PROVIDER_ID_ATTRIBUTE = "evalution.prompt.provider.id";
530
+ /**
531
+ * Attribute name a span can set to include an array of input parameters used
532
+ * to construct the final prompt.
533
+ */
534
+ declare const PROMPT_INPUTS_ATTRIBUTE = "evalution.prompt.inputs";
535
+ interface PromptSpanInfo {
536
+ name: string;
537
+ id?: string;
538
+ functionParameters?: any[];
539
+ }
540
+ declare function getPromptSpanAttributes(prompt: PromptSpanInfo, attributes?: Attributes): Record<string, AttributeValue>;
520
541
  /**
521
542
  * Wraps a {@link Tracer} so that every span it produces is tagged with the
522
543
  * attributes that associate it with a prompt — the prompt's name
@@ -537,10 +558,7 @@ declare const PROMPT_NAME_ATTRIBUTE = "gen_ai.prompt.name";
537
558
  * @returns A tracer that forwards to `tracer` while attaching the prompt
538
559
  * attributes to each span it creates.
539
560
  */
540
- declare function createTracerForPrompt(prompt: {
541
- name: string;
542
- id?: string;
543
- }, tracer?: Tracer): Tracer;
561
+ declare function createTracerForPrompt(prompt: PromptSpanInfo, tracer?: Tracer): Tracer;
544
562
  //#endregion
545
563
  //#region src/trace/trace-provider.d.ts
546
564
  /**
@@ -682,8 +700,10 @@ type FileWatchCallback = (eventType: ChangeEventType, filePath: string) => void;
682
700
  * Abstraction over file system I/O used throughout Evalution.
683
701
  *
684
702
  * Swap in a different implementation to adapt Evalution to non-local
685
- * environments or to make tests fully in-memory (see {@link MemoryFileProvider}).
686
- * {@link LocalFileProvider} is the default implementation for production use.
703
+ * environments or to make tests fully in-memory. The
704
+ * {@link MemoryFileProvider} (in `./file-provider-memory.ts`) keeps everything
705
+ * in-process with no Node-only dependencies; {@link LocalFileProvider} (in
706
+ * `./file-provider-local.ts`) is the default implementation for production use.
687
707
  */
688
708
  interface FileProvider {
689
709
  /**
@@ -725,12 +745,37 @@ interface FileProvider {
725
745
  */
726
746
  watch(patterns: readonly string[], options: FileWatchOptions, callback: FileWatchCallback): () => void;
727
747
  }
748
+ //#endregion
749
+ //#region src/file-provider-local.d.ts
750
+ /**
751
+ * A {@link FileProvider} backed by the local file system.
752
+ *
753
+ * Uses `fs/promises` for I/O, `fs/promises.glob` (Node.js ≥ 22) for pattern
754
+ * matching, and [chokidar](https://github.com/paulmillr/chokidar) for file
755
+ * watching.
756
+ *
757
+ * This is the default implementation used by {@link FilePromptProvider} and
758
+ * {@link TSPromptFileType} when no custom provider is supplied.
759
+ */
760
+ declare class LocalFileProvider implements FileProvider {
761
+ readFile(filePath: string): Promise<string>;
762
+ writeFile(filePath: string, content: string): Promise<void>;
763
+ deleteFile(filePath: string): Promise<void>;
764
+ import(filePath: string): Promise<any>;
765
+ glob(pattern: string, options?: GlobOptions): AsyncIterableIterator<string>;
766
+ watch(patterns: readonly string[], options: FileWatchOptions, callback: FileWatchCallback): () => void;
767
+ }
768
+ //#endregion
769
+ //#region src/file-provider-memory.d.ts
728
770
  /**
729
771
  * An in-memory {@link FileProvider} backed by a `Map<string, string>`.
730
772
  *
731
- * Intended for unit tests all file I/O stays in-process with no disk access.
732
- * Calling {@link writeFile} triggers any active {@link watch} callbacks
733
- * synchronously, making it easy to test reactive code paths.
773
+ * Intended for unit tests and non-local environments (e.g. a browser or
774
+ * service-worker bundle) all file I/O stays in-process with no disk access.
775
+ * It depends only on `node:path` and `minimatch`, so it carries no Node-only
776
+ * runtime dependencies (no `node:fs`, `chokidar`, etc.). Calling
777
+ * {@link writeFile} triggers any active {@link watch} callbacks synchronously,
778
+ * making it easy to test reactive code paths.
734
779
  *
735
780
  * @example
736
781
  * ```ts
@@ -755,24 +800,6 @@ declare class MemoryFileProvider implements FileProvider {
755
800
  watch(patterns: readonly string[], options: FileWatchOptions, callback: FileWatchCallback): () => void;
756
801
  private notifyWatchers;
757
802
  }
758
- /**
759
- * A {@link FileProvider} backed by the local file system.
760
- *
761
- * Uses `fs/promises` for I/O, `fs/promises.glob` (Node.js ≥ 22) for pattern
762
- * matching, and [chokidar](https://github.com/paulmillr/chokidar) for file
763
- * watching.
764
- *
765
- * This is the default implementation used by {@link FilePromptProvider} and
766
- * {@link TSPromptFileType} when no custom provider is supplied.
767
- */
768
- declare class LocalFileProvider implements FileProvider {
769
- readFile(filePath: string): Promise<string>;
770
- writeFile(filePath: string, content: string): Promise<void>;
771
- deleteFile(filePath: string): Promise<void>;
772
- import(filePath: string): Promise<any>;
773
- glob(pattern: string, options?: GlobOptions): AsyncIterableIterator<string>;
774
- watch(patterns: readonly string[], options: FileWatchOptions, callback: FileWatchCallback): () => void;
775
- }
776
803
  //#endregion
777
804
  //#region src/sdk/sdk-adapter.d.ts
778
805
  /**
@@ -780,6 +807,14 @@ declare class LocalFileProvider implements FileProvider {
780
807
  *
781
808
  * Pass an instance of this to {@link FilePromptProvider} via the
782
809
  * `sdk` option.
810
+ *
811
+ * Each `SDKAdapter` implementation should be paired with a companion package
812
+ * (named by {@link SDKAdapter.promptsHelperImport}) that exports a `prompts`
813
+ * function satisfying the {@link PromptsHelper} type. That function is the user-facing entry
814
+ * point for defining prompts that work with Evalution. It accepts a {@link PromptsHelperOptions}
815
+ * and a factory that can optionally receive SDK-specific parameters. The factory should return a
816
+ * record of prompt functions. Prompt functions should return a configuration that enables OpenTelemetry
817
+ * reporting, if possible, with the attributes returned by {@link getPromptSpanAttributes}.
783
818
  */
784
819
  interface SDKAdapter {
785
820
  /**
@@ -801,13 +836,11 @@ interface SDKAdapter {
801
836
  */
802
837
  getModelParameters(rootDir: string): PropDefinition$1[];
803
838
  /**
804
- * Executes a prompt config object and returns either a result object (when
805
- * `stream` is `false`) or an async text iterable (when `stream` is `true`).
839
+ * Executes a prompt config object.
806
840
  *
807
841
  * @param config - The config object returned by the prompt function.
808
- * @param stream - When `true`, returns a streaming text iterator.
809
842
  */
810
- executeConfig(config: any, stream: boolean): Promise<any>;
843
+ executeConfig(config: any): Promise<void>;
811
844
  /**
812
845
  * Convert a low-level {@link ParsedPrompt} produced by a
813
846
  * {@link PromptFileType} into a {@link NormalizedPrompt} that the UI can
@@ -988,7 +1021,6 @@ declare class FilePromptProvider implements PromptProvider<NormalizedFilePrompt>
988
1021
  private includePatterns;
989
1022
  private ignorePatterns;
990
1023
  private sdkAdapter;
991
- private suppressedWatchEvents;
992
1024
  constructor({
993
1025
  id,
994
1026
  rootDir,
@@ -1005,13 +1037,11 @@ declare class FilePromptProvider implements PromptProvider<NormalizedFilePrompt>
1005
1037
  private normalizeFilePrompt;
1006
1038
  getModelCatalog(): Promise<ModelCatalog>;
1007
1039
  getModelParameters(): PropDefinition[];
1008
- execute(promptId: string, params: any[], stream: boolean): Promise<any>;
1040
+ execute(promptId: string, params: any[]): Promise<void>;
1009
1041
  renamePrompt(promptId: string, newName: string): Promise<NormalizedFilePrompt>;
1010
1042
  addPrompt(partial: Partial<NormalizedFilePrompt>): Promise<NormalizedFilePrompt | AddPromptContext>;
1011
1043
  watch(callback: (event: PromptChangeEvent) => void): () => void;
1012
1044
  private ensureFiles;
1013
- private suppressNextWatchEvent;
1014
- private consumeSuppressedWatchEvent;
1015
1045
  private findPromptFiles;
1016
1046
  private parsePromptId;
1017
1047
  private listDirectories;
@@ -1234,7 +1264,7 @@ declare class GeminiInteractionsSDK implements SDKAdapter {
1234
1264
  }];
1235
1265
  }>;
1236
1266
  getModelParameters(rootDir: string): PropDefinition$1[];
1237
- executeConfig(config: BaseCreateInteractionParams, stream: boolean): Promise<any>;
1267
+ executeConfig(config: BaseCreateInteractionParams): Promise<void>;
1238
1268
  normalizePrompt(prompt: ParsedPrompt): NormalizedPrompt;
1239
1269
  denormalizeUpdates(updates: NormalizedPromptUpdates, currentValues?: Record<string, PropValue$1>): Record<string, ModelPropValue | null>;
1240
1270
  }
@@ -1296,11 +1326,6 @@ interface SetupInstallPackageStep extends SetupStepBase {
1296
1326
  * server to run it.
1297
1327
  */
1298
1328
  type SetupStep = SetupCreateConfigStep | SetupRunCommandStep | SetupInstallPackageStep;
1299
- /**
1300
- * The shell command a run-style step executes. `install_package` steps map to
1301
- * `npm i <package>`; `run_command` steps carry their command verbatim.
1302
- */
1303
- declare function setupStepCommand(step: SetupRunCommandStep | SetupInstallPackageStep): string;
1304
1329
  /**
1305
1330
  * A named onboarding task for a single AI SDK: what to show in the manual-setup
1306
1331
  * picker, plus the ordered steps that wire the SDK up.
@@ -1327,7 +1352,10 @@ interface SetupTask {
1327
1352
  */
1328
1353
  declare class VercelAISDK implements SDKAdapter {
1329
1354
  readonly promptsHelperImport: "@evalution/vercel-ai-sdk";
1330
- /** Onboarding task: install the SDK package, then drop a starter config. */
1355
+ /**
1356
+ * Onboarding task: install the SDK package, then drop a starter config.
1357
+ * @internal
1358
+ */
1331
1359
  static readonly setupTask: SetupTask;
1332
1360
  getModelCatalog(): Promise<{
1333
1361
  modelValueTypes: {
@@ -1360,7 +1388,7 @@ declare class VercelAISDK implements SDKAdapter {
1360
1388
  models: ModelInfo[];
1361
1389
  }>;
1362
1390
  getModelParameters(rootDir: string): PropDefinition$1[];
1363
- executeConfig(config: any, stream: boolean): Promise<any>;
1391
+ executeConfig(config: any): Promise<void>;
1364
1392
  normalizePrompt(prompt: ParsedPrompt): NormalizedPrompt;
1365
1393
  denormalizeUpdates(updates: NormalizedPromptUpdates, _currentValues?: Record<string, PropValue$1>): Record<string, ModelPropValue | null>;
1366
1394
  }
@@ -1437,4 +1465,4 @@ declare class MemoryTraceProvider extends BaseOTelTraceProvider {
1437
1465
  protected addOrUpdateSpan(span: Span): Promise<Span>;
1438
1466
  }
1439
1467
  //#endregion
1440
- export { type AddPromptContext, type AddPromptField, type CalleeBinding, type ChangeEventType, type EvalutionConfig, type ExecuteRequest, type ExecuteResponse, type ExtractedProps, type FilePromptMetadata, FilePromptProvider, type FilePromptProviderOptions, type FileProvider, type FileWatchCallback, type FileWatchOptions, GeminiInteractionsSDK, type GlobOptions, type LLMSpanDetails, LocalFileProvider, MemoryFileProvider, MemoryTraceProvider, type ModelCatalog, type ModelGroupInfo, type ModelInfo, type ModelPropValue, type ModelValueType, type NormalizedFilePrompt, type NormalizedMessage, type NormalizedParameter, type NormalizedPrompt, type NormalizedPromptUpdates, type NormalizedToolCall, PROMPT_ID_ATTRIBUTE, PROMPT_NAME_ATTRIBUTE, PROMPT_PROVIDER_ID_ATTRIBUTE, type ParsedFilePrompt, type ParsedPrompt, type PromptChangeEvent, type PromptFileType, type PromptID, type PromptProvider, type PromptProviderInfo, type PropDefinition, type PropValue, type SDKAdapter, SPAN_KIND_ATTRIBUTE, type SetupCreateConfigStep, type SetupInstallPackageStep, type SetupRunCommandStep, type SetupStep, type SetupStepBase, type SetupTask, type SourceSpan, type Span, type SpanKind, type SpanMessage, TSPromptFileType, type Trace, type TraceChangeEvent, type TraceChangeType, type TraceProvider, type TraceProviderInfo, type TraceStreamEvent, type TraceSummary, type TraceWithSpans, VercelAISDK, createTracerForPrompt, setupStepCommand };
1468
+ export { type AddPromptContext, type AddPromptField, type CalleeBinding, type ChangeEventType, type EvalutionConfig, type ExecuteRequest, type ExecuteResponse, type ExtractedProps, type FilePromptMetadata, FilePromptProvider, type FilePromptProviderOptions, type FileProvider, type FileWatchCallback, type FileWatchOptions, GeminiInteractionsSDK, type GlobOptions, type LLMSpanDetails, LocalFileProvider, MemoryFileProvider, MemoryTraceProvider, type ModelCatalog, type ModelGroupInfo, type ModelInfo, type ModelPropValue, type ModelValueType, type NormalizedFilePrompt, type NormalizedMessage, type NormalizedParameter, type NormalizedPrompt, type NormalizedPromptUpdates, type NormalizedToolCall, PROMPT_ID_ATTRIBUTE, PROMPT_INPUTS_ATTRIBUTE, PROMPT_NAME_ATTRIBUTE, PROMPT_PROVIDER_ID_ATTRIBUTE, type ParsedFilePrompt, type ParsedPrompt, type PromptChangeEvent, type PromptFileType, type PromptID, type PromptProvider, type PromptProviderInfo, type PromptSpanInfo, type PromptsFactory, type PromptsHelper, type PromptsHelperOptions, type PropDefinition, type PropValue, type SDKAdapter, SPAN_KIND_ATTRIBUTE, type SourceSpan, type Span, type SpanKind, type SpanMessage, TSPromptFileType, type Trace, type TraceChangeEvent, type TraceChangeType, type TraceProvider, type TraceProviderInfo, type TraceStreamEvent, type TraceSummary, type TraceWithSpans, VercelAISDK, createTracerForPrompt, getPromptSpanAttributes };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as MemoryTraceProvider, c as PROMPT_PROVIDER_ID_ATTRIBUTE, d as isEditable, i as setupStepCommand, l as SPAN_KIND_ATTRIBUTE, n as findPackageDts, o as PROMPT_ID_ATTRIBUTE, s as PROMPT_NAME_ATTRIBUTE, t as VercelAISDK, u as createTracerForPrompt } from "./vercel-ai-sdk-CareWPDM.js";
1
+ import { a as MemoryTraceProvider, c as PROMPT_NAME_ATTRIBUTE, d as createTracerForPrompt, f as getPromptSpanAttributes, l as PROMPT_PROVIDER_ID_ATTRIBUTE, n as findPackageDts, o as PROMPT_ID_ATTRIBUTE, p as isEditable, s as PROMPT_INPUTS_ATTRIBUTE, t as VercelAISDK, u as SPAN_KIND_ATTRIBUTE } from "./vercel-ai-sdk-B5BwUGKp.js";
2
2
  import fs, { glob } from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { pathToFileURL } from "node:url";
@@ -8,13 +8,79 @@ import ts from "typescript";
8
8
  import chokidar from "chokidar";
9
9
  import { makeRe, minimatch } from "minimatch";
10
10
  import { GoogleGenAI } from "@google/genai";
11
- //#region src/file-provider.ts
11
+ //#region src/file-provider-local.ts
12
+ /**
13
+ * A {@link FileProvider} backed by the local file system.
14
+ *
15
+ * Uses `fs/promises` for I/O, `fs/promises.glob` (Node.js ≥ 22) for pattern
16
+ * matching, and [chokidar](https://github.com/paulmillr/chokidar) for file
17
+ * watching.
18
+ *
19
+ * This is the default implementation used by {@link FilePromptProvider} and
20
+ * {@link TSPromptFileType} when no custom provider is supplied.
21
+ */
22
+ var LocalFileProvider = class {
23
+ async readFile(filePath) {
24
+ return fs.readFile(filePath, "utf-8");
25
+ }
26
+ async writeFile(filePath, content) {
27
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
28
+ await fs.writeFile(filePath, content, "utf-8");
29
+ }
30
+ async deleteFile(filePath) {
31
+ await fs.unlink(filePath);
32
+ }
33
+ async import(filePath) {
34
+ return import(pathToFileURL(filePath).href);
35
+ }
36
+ async *glob(pattern, options = {}) {
37
+ const { cwd, ignore = [], absolute = false } = options;
38
+ const baseCwd = cwd ?? process.cwd();
39
+ for await (const file of glob(pattern, { cwd: baseCwd })) {
40
+ const relativePath = file.replace(/\\/g, "/");
41
+ if (ignore.some((p) => minimatch(relativePath, p))) continue;
42
+ yield absolute ? path.resolve(baseCwd, file) : file;
43
+ }
44
+ }
45
+ watch(patterns, options, callback) {
46
+ const cwd = options.cwd ?? process.cwd();
47
+ const ignored = options.ignored ?? [];
48
+ const includeMatchers = patterns.map((p) => makeRe(p)).filter((re) => re !== false);
49
+ const matches = (fp) => includeMatchers.some((re) => re.test(fp));
50
+ const watcher = chokidar.watch(".", {
51
+ cwd,
52
+ ignored: (absPath) => {
53
+ const rel = path.relative(cwd, absPath).replace(/\\/g, "/");
54
+ return ignored.some((p) => minimatch(rel, p, { dot: true }));
55
+ },
56
+ persistent: true,
57
+ ignoreInitial: options.ignoreInitial ?? true
58
+ });
59
+ watcher.on("change", (fp) => {
60
+ if (matches(fp)) callback("change", fp);
61
+ });
62
+ watcher.on("add", (fp) => {
63
+ if (matches(fp)) callback("add", fp);
64
+ });
65
+ watcher.on("unlink", (fp) => {
66
+ if (matches(fp)) callback("remove", fp);
67
+ });
68
+ return () => {
69
+ watcher.close();
70
+ };
71
+ }
72
+ };
73
+ //#endregion
74
+ //#region src/file-provider-memory.ts
12
75
  /**
13
76
  * An in-memory {@link FileProvider} backed by a `Map<string, string>`.
14
77
  *
15
- * Intended for unit tests all file I/O stays in-process with no disk access.
16
- * Calling {@link writeFile} triggers any active {@link watch} callbacks
17
- * synchronously, making it easy to test reactive code paths.
78
+ * Intended for unit tests and non-local environments (e.g. a browser or
79
+ * service-worker bundle) all file I/O stays in-process with no disk access.
80
+ * It depends only on `node:path` and `minimatch`, so it carries no Node-only
81
+ * runtime dependencies (no `node:fs`, `chokidar`, etc.). Calling
82
+ * {@link writeFile} triggers any active {@link watch} callbacks synchronously,
83
+ * making it easy to test reactive code paths.
18
84
  *
19
85
  * @example
20
86
  * ```ts
@@ -85,67 +151,6 @@ var MemoryFileProvider = class {
85
151
  }
86
152
  }
87
153
  };
88
- /**
89
- * A {@link FileProvider} backed by the local file system.
90
- *
91
- * Uses `fs/promises` for I/O, `fs/promises.glob` (Node.js ≥ 22) for pattern
92
- * matching, and [chokidar](https://github.com/paulmillr/chokidar) for file
93
- * watching.
94
- *
95
- * This is the default implementation used by {@link FilePromptProvider} and
96
- * {@link TSPromptFileType} when no custom provider is supplied.
97
- */
98
- var LocalFileProvider = class {
99
- async readFile(filePath) {
100
- return fs.readFile(filePath, "utf-8");
101
- }
102
- async writeFile(filePath, content) {
103
- await fs.mkdir(path.dirname(filePath), { recursive: true });
104
- await fs.writeFile(filePath, content, "utf-8");
105
- }
106
- async deleteFile(filePath) {
107
- await fs.unlink(filePath);
108
- }
109
- async import(filePath) {
110
- return import(pathToFileURL(filePath).href);
111
- }
112
- async *glob(pattern, options = {}) {
113
- const { cwd, ignore = [], absolute = false } = options;
114
- const baseCwd = cwd ?? process.cwd();
115
- for await (const file of glob(pattern, { cwd: baseCwd })) {
116
- const relativePath = file.replace(/\\/g, "/");
117
- if (ignore.some((p) => minimatch(relativePath, p))) continue;
118
- yield absolute ? path.resolve(baseCwd, file) : file;
119
- }
120
- }
121
- watch(patterns, options, callback) {
122
- const cwd = options.cwd ?? process.cwd();
123
- const ignored = options.ignored ?? [];
124
- const includeMatchers = patterns.map((p) => makeRe(p)).filter((re) => re !== false);
125
- const matches = (fp) => includeMatchers.some((re) => re.test(fp));
126
- const watcher = chokidar.watch(".", {
127
- cwd,
128
- ignored: (absPath) => {
129
- const rel = path.relative(cwd, absPath).replace(/\\/g, "/");
130
- return ignored.some((p) => minimatch(rel, p, { dot: true }));
131
- },
132
- persistent: true,
133
- ignoreInitial: options.ignoreInitial ?? true
134
- });
135
- watcher.on("change", (fp) => {
136
- if (matches(fp)) callback("change", fp);
137
- });
138
- watcher.on("add", (fp) => {
139
- if (matches(fp)) callback("add", fp);
140
- });
141
- watcher.on("unlink", (fp) => {
142
- if (matches(fp)) callback("remove", fp);
143
- });
144
- return () => {
145
- watcher.close();
146
- };
147
- }
148
- };
149
154
  //#endregion
150
155
  //#region src/prompt/file/ts/ts-prompt-file-type.ts
151
156
  /**
@@ -183,7 +188,7 @@ var TSPromptFileType = class {
183
188
  return `import { prompts } from ${JSON.stringify(importPath)};
184
189
 
185
190
  export default prompts(
186
- ${JSON.stringify(promptsId)},
191
+ { id: ${JSON.stringify(promptsId)} },
187
192
  () => ({
188
193
  ${key}: () => ({
189
194
  })
@@ -382,10 +387,9 @@ export default prompts(
382
387
  }
383
388
  };
384
389
  /**
385
- * If `expr` is a call like `prompts(id, factory)` (or the legacy `prompts(factory)`)
386
- * whose factory immediately returns an object literal, return that object literal
387
- * together with the module ID — the first string-literal argument, when present.
388
- * Otherwise null.
390
+ * If `expr` is a call like `prompts({ id }, factory)` whose factory immediately
391
+ * returns an object literal, return that object literal together with the module
392
+ * ID extracted from the options object. Otherwise null.
389
393
  */
390
394
  function findPromptsHelperCall(expr) {
391
395
  if (!ts.isCallExpression(expr)) return null;
@@ -397,9 +401,12 @@ function findPromptsHelperCall(expr) {
397
401
  const first = expr.arguments[0];
398
402
  return {
399
403
  object,
400
- moduleId: first && ts.isStringLiteralLike(first) ? first.text : void 0
404
+ moduleId: first && ts.isObjectLiteralExpression(first) ? extractStringProperty(first, "id") : void 0
401
405
  };
402
406
  }
407
+ function extractStringProperty(obj, key) {
408
+ for (const prop of obj.properties) if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && prop.name.text === key && ts.isStringLiteralLike(prop.initializer)) return prop.initializer.text;
409
+ }
403
410
  function getPropertyName(prop) {
404
411
  if (ts.isMethodDeclaration(prop) || ts.isPropertyAssignment(prop)) {
405
412
  const name = prop.name;
@@ -600,7 +607,6 @@ var FilePromptProvider = class {
600
607
  includePatterns;
601
608
  ignorePatterns;
602
609
  sdkAdapter;
603
- suppressedWatchEvents = /* @__PURE__ */ new Map();
604
610
  constructor({ id = "fs" + (defaultIDCounter++ ? defaultIDCounter : ""), rootDir = process.cwd(), fileProvider = new LocalFileProvider(), fileType, includePatterns, ignorePatterns = DEFAULT_IGNORE_PATTERNS, sdk }) {
605
611
  fileType ??= new TSPromptFileType(fileProvider);
606
612
  this.id = id;
@@ -626,7 +632,6 @@ var FilePromptProvider = class {
626
632
  const { definitions, values } = parsed.extractedProps;
627
633
  const rawUpdates = this.sdkAdapter.denormalizeUpdates(updates, values);
628
634
  for (const [propertyName, value] of Object.entries(rawUpdates)) {
629
- this.suppressNextWatchEvent(filePath, "change");
630
635
  const propDef = definitions.find((d) => d.name === propertyName);
631
636
  const currentValue = values?.[propertyName];
632
637
  if (value === null) {
@@ -663,14 +668,13 @@ var FilePromptProvider = class {
663
668
  getModelParameters() {
664
669
  return this.sdkAdapter.getModelParameters(this.rootDir);
665
670
  }
666
- async execute(promptId, params, stream) {
671
+ async execute(promptId, params) {
667
672
  const [filePath, promptName] = this.parsePromptId(promptId);
668
673
  const config = await this.fileType.loadConfig(filePath, promptName, params);
669
- return this.sdkAdapter.executeConfig(config, stream);
674
+ await this.sdkAdapter.executeConfig(config);
670
675
  }
671
676
  async renamePrompt(promptId, newName) {
672
677
  const [filePath, oldName] = this.parsePromptId(promptId);
673
- this.suppressNextWatchEvent(filePath, "change");
674
678
  await this.fileType.renamePrompt(filePath, oldName, newName);
675
679
  const relFilePath = path.relative(this.rootDir, filePath);
676
680
  const prompt = await this.getPrompt(`${relFilePath}#${newName}`);
@@ -687,7 +691,6 @@ var FilePromptProvider = class {
687
691
  const promptsId = firstDot >= 0 ? baseName.slice(0, firstDot) : baseName;
688
692
  const name = partial.name ?? promptsId;
689
693
  const content = this.fileType.newPromptSkeleton(promptsId, name, this.sdkAdapter.promptsHelperImport);
690
- this.suppressNextWatchEvent(absPath, "add");
691
694
  await this.fileProvider.writeFile(absPath, content);
692
695
  if (this.files && !this.files.includes(absPath)) this.files.push(absPath);
693
696
  const prompt = await this.getPrompt(`${normalizedRelFilePath}#${name}`);
@@ -741,7 +744,6 @@ var FilePromptProvider = class {
741
744
  ignored: this.ignorePatterns
742
745
  }, async (eventType, filePath) => {
743
746
  const absolutePath = this.resolveFilePath(filePath);
744
- if (this.consumeSuppressedWatchEvent(absolutePath, eventType)) return;
745
747
  if (eventType === "change" || eventType === "add") {
746
748
  if (this.files && !this.files.includes(absolutePath)) this.files.push(absolutePath);
747
749
  (await this.fileType.parsePrompts([absolutePath], this.rootDir)).forEach((prompt) => {
@@ -762,30 +764,6 @@ var FilePromptProvider = class {
762
764
  async ensureFiles() {
763
765
  if (!this.files) this.files = await Array.fromAsync(this.findPromptFiles());
764
766
  }
765
- suppressNextWatchEvent(filePath, eventType) {
766
- if (eventType !== "change" && eventType !== "add") return;
767
- const key = `${eventType}:${filePath}`;
768
- const entry = this.suppressedWatchEvents.get(key);
769
- this.suppressedWatchEvents.set(key, {
770
- remaining: (entry?.remaining ?? 0) + 1,
771
- expiresAt: Date.now() + 2e3
772
- });
773
- }
774
- consumeSuppressedWatchEvent(filePath, eventType) {
775
- const key = `${eventType}:${filePath}`;
776
- const entry = this.suppressedWatchEvents.get(key);
777
- if (!entry) return false;
778
- if (entry.expiresAt < Date.now()) {
779
- this.suppressedWatchEvents.delete(key);
780
- return false;
781
- }
782
- if (entry.remaining <= 1) this.suppressedWatchEvents.delete(key);
783
- else this.suppressedWatchEvents.set(key, {
784
- remaining: entry.remaining - 1,
785
- expiresAt: entry.expiresAt
786
- });
787
- return true;
788
- }
789
767
  async *findPromptFiles() {
790
768
  const uniqueFiles = /* @__PURE__ */ new Set();
791
769
  for (const pattern of this.includePatterns) {
@@ -1116,26 +1094,22 @@ var GeminiInteractionsSDK = class {
1116
1094
  });
1117
1095
  }
1118
1096
  getModelParameters(rootDir) {
1119
- const dtsPath = findPackageDts("@google/genai", "dist/genai.d.ts", rootDir);
1120
- if (dtsPath) try {
1121
- const sourceText = fs$1.readFileSync(dtsPath, "utf-8");
1122
- const sourceFile = ts.createSourceFile(dtsPath, sourceText, ts.ScriptTarget.Latest, true);
1123
- const decl = findTypeDeclaration(sourceFile, "GenerationConfig_2");
1124
- if (decl) return extractPropertiesFromDeclaration(decl, sourceFile).definitions;
1097
+ try {
1098
+ const dtsPath = findPackageDts("@google/genai", "dist/genai.d.ts", rootDir);
1099
+ if (dtsPath) {
1100
+ const sourceText = fs$1.readFileSync(dtsPath, "utf-8");
1101
+ const sourceFile = ts.createSourceFile(dtsPath, sourceText, ts.ScriptTarget.Latest, true);
1102
+ const decl = findTypeDeclaration(sourceFile, "GenerationConfig_2");
1103
+ if (decl) return extractPropertiesFromDeclaration(decl, sourceFile).definitions;
1104
+ }
1125
1105
  } catch {}
1126
1106
  return FALLBACK_GENERATION_CONFIG_PARAMS;
1127
1107
  }
1128
- async executeConfig(config, stream) {
1129
- const result = await new GoogleGenAI({}).interactions.create({
1108
+ async executeConfig(config) {
1109
+ await new GoogleGenAI({}).interactions.create({
1130
1110
  ...config,
1131
- stream,
1132
1111
  store: false
1133
1112
  });
1134
- if ("id" in result) return {
1135
- text: (result.outputs ?? []).find((o) => o.type === "text")?.text ?? "",
1136
- usage: result.usage
1137
- };
1138
- else return streamTextFromSSE(result);
1139
1113
  }
1140
1114
  normalizePrompt(prompt) {
1141
1115
  const { definitions, values } = prompt.extractedProps;
@@ -1313,13 +1287,5 @@ function extractMessages(value) {
1313
1287
  }
1314
1288
  return results;
1315
1289
  }
1316
- /**
1317
- * Yields text chunks from the Interactions API SSE stream.
1318
- */
1319
- async function* streamTextFromSSE(stream) {
1320
- for await (const chunk of stream) if (chunk.event_type === "content.delta") {
1321
- if (chunk.delta?.type === "text" && chunk.delta.text) yield chunk.delta.text;
1322
- }
1323
- }
1324
1290
  //#endregion
1325
- export { FilePromptProvider, GeminiInteractionsSDK, LocalFileProvider, MemoryFileProvider, MemoryTraceProvider, PROMPT_ID_ATTRIBUTE, PROMPT_NAME_ATTRIBUTE, PROMPT_PROVIDER_ID_ATTRIBUTE, SPAN_KIND_ATTRIBUTE, TSPromptFileType, VercelAISDK, createTracerForPrompt, setupStepCommand };
1291
+ export { FilePromptProvider, GeminiInteractionsSDK, LocalFileProvider, MemoryFileProvider, MemoryTraceProvider, PROMPT_ID_ATTRIBUTE, PROMPT_INPUTS_ATTRIBUTE, PROMPT_NAME_ATTRIBUTE, PROMPT_PROVIDER_ID_ATTRIBUTE, SPAN_KIND_ATTRIBUTE, TSPromptFileType, VercelAISDK, createTracerForPrompt, getPromptSpanAttributes };