agentfootprint 9.12.0 → 9.14.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 (82) hide show
  1. package/AGENTS.md +3 -2
  2. package/dist/adapters/llm/GeminiProvider.js +519 -0
  3. package/dist/adapters/llm/GeminiProvider.js.map +1 -0
  4. package/dist/adapters/llm/contextWindow.js +20 -0
  5. package/dist/adapters/llm/contextWindow.js.map +1 -1
  6. package/dist/adapters/llm/createProvider.js +3 -0
  7. package/dist/adapters/llm/createProvider.js.map +1 -1
  8. package/dist/adapters/llm/googleGenAI.js +109 -0
  9. package/dist/adapters/llm/googleGenAI.js.map +1 -0
  10. package/dist/core/agent/AgentBuilder.js +14 -5
  11. package/dist/core/agent/AgentBuilder.js.map +1 -1
  12. package/dist/embedders/index.js +233 -1
  13. package/dist/embedders/index.js.map +1 -1
  14. package/dist/esm/adapters/llm/GeminiProvider.d.ts +204 -0
  15. package/dist/esm/adapters/llm/GeminiProvider.js +514 -0
  16. package/dist/esm/adapters/llm/GeminiProvider.js.map +1 -0
  17. package/dist/esm/adapters/llm/contextWindow.js +20 -0
  18. package/dist/esm/adapters/llm/contextWindow.js.map +1 -1
  19. package/dist/esm/adapters/llm/createProvider.d.ts +4 -1
  20. package/dist/esm/adapters/llm/createProvider.js +3 -0
  21. package/dist/esm/adapters/llm/createProvider.js.map +1 -1
  22. package/dist/esm/adapters/llm/googleGenAI.d.ts +67 -0
  23. package/dist/esm/adapters/llm/googleGenAI.js +105 -0
  24. package/dist/esm/adapters/llm/googleGenAI.js.map +1 -0
  25. package/dist/esm/core/agent/AgentBuilder.d.ts +5 -2
  26. package/dist/esm/core/agent/AgentBuilder.js +14 -5
  27. package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
  28. package/dist/esm/embedders/index.d.ts +188 -1
  29. package/dist/esm/embedders/index.js +231 -0
  30. package/dist/esm/embedders/index.js.map +1 -1
  31. package/dist/esm/memory/define.d.ts +1 -1
  32. package/dist/esm/memory/define.js +113 -14
  33. package/dist/esm/memory/define.js.map +1 -1
  34. package/dist/esm/memory/define.types.d.ts +69 -4
  35. package/dist/esm/memory/define.types.js.map +1 -1
  36. package/dist/esm/memory/pipeline/default.d.ts +22 -0
  37. package/dist/esm/memory/pipeline/default.js +19 -3
  38. package/dist/esm/memory/pipeline/default.js.map +1 -1
  39. package/dist/esm/memory/stages/summarize.d.ts +193 -54
  40. package/dist/esm/memory/stages/summarize.js +370 -34
  41. package/dist/esm/memory/stages/summarize.js.map +1 -1
  42. package/dist/esm/memory/strategies.d.ts +7 -1
  43. package/dist/esm/memory/strategies.js +25 -11
  44. package/dist/esm/memory/strategies.js.map +1 -1
  45. package/dist/esm/providers.d.ts +3 -0
  46. package/dist/esm/providers.js +2 -0
  47. package/dist/esm/providers.js.map +1 -1
  48. package/dist/memory/define.js +113 -14
  49. package/dist/memory/define.js.map +1 -1
  50. package/dist/memory/define.types.js.map +1 -1
  51. package/dist/memory/pipeline/default.js +19 -3
  52. package/dist/memory/pipeline/default.js.map +1 -1
  53. package/dist/memory/stages/summarize.js +374 -35
  54. package/dist/memory/stages/summarize.js.map +1 -1
  55. package/dist/memory/strategies.js +25 -11
  56. package/dist/memory/strategies.js.map +1 -1
  57. package/dist/providers.js +5 -1
  58. package/dist/providers.js.map +1 -1
  59. package/dist/types/adapters/llm/GeminiProvider.d.ts +205 -0
  60. package/dist/types/adapters/llm/GeminiProvider.d.ts.map +1 -0
  61. package/dist/types/adapters/llm/contextWindow.d.ts.map +1 -1
  62. package/dist/types/adapters/llm/createProvider.d.ts +4 -1
  63. package/dist/types/adapters/llm/createProvider.d.ts.map +1 -1
  64. package/dist/types/adapters/llm/googleGenAI.d.ts +68 -0
  65. package/dist/types/adapters/llm/googleGenAI.d.ts.map +1 -0
  66. package/dist/types/core/agent/AgentBuilder.d.ts +5 -2
  67. package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
  68. package/dist/types/embedders/index.d.ts +188 -1
  69. package/dist/types/embedders/index.d.ts.map +1 -1
  70. package/dist/types/memory/define.d.ts +1 -1
  71. package/dist/types/memory/define.d.ts.map +1 -1
  72. package/dist/types/memory/define.types.d.ts +69 -4
  73. package/dist/types/memory/define.types.d.ts.map +1 -1
  74. package/dist/types/memory/pipeline/default.d.ts +22 -0
  75. package/dist/types/memory/pipeline/default.d.ts.map +1 -1
  76. package/dist/types/memory/stages/summarize.d.ts +193 -54
  77. package/dist/types/memory/stages/summarize.d.ts.map +1 -1
  78. package/dist/types/memory/strategies.d.ts +7 -1
  79. package/dist/types/memory/strategies.d.ts.map +1 -1
  80. package/dist/types/providers.d.ts +3 -0
  81. package/dist/types/providers.d.ts.map +1 -1
  82. package/package.json +7 -1
@@ -0,0 +1,204 @@
1
+ /**
2
+ * GeminiProvider — wraps `@google/genai` as an `LLMProvider` (9.13.0).
3
+ *
4
+ * Pattern: Adapter (GoF) + Ports-and-Adapters (Cockburn 2005).
5
+ * Role: Outer ring — translates `LLMRequest`/`LLMResponse` to/from Google's
6
+ * `generateContent` API. Knows nothing about agents, recorders, or
7
+ * compositions.
8
+ * Emits: N/A — providers don't emit; recorders observe via Agent.
9
+ *
10
+ * ─── Two doors, one adapter ─────────────────────────────────────────
11
+ *
12
+ * The same SDK reaches two different services, and which one you get is a
13
+ * property of the OPTIONS, not of a separate factory:
14
+ *
15
+ * • **Vertex** — `gemini({ project, location })` builds
16
+ * `new GoogleGenAI({ vertexai: true, project, location, googleAuthOptions })`.
17
+ * Auth is Application Default Credentials (env key file, gcloud user
18
+ * credentials, or the metadata server on GCE / Cloud Run / Agent Runtime).
19
+ * No API key exists on this path.
20
+ * • **Gemini API (AI Studio)** — `gemini({ apiKey })` builds
21
+ * `new GoogleGenAI({ apiKey })`. One key, no cloud project.
22
+ *
23
+ * Neither is guessed. The factory refuses at construction when it can resolve
24
+ * neither a project nor a key, naming both doors — because the SDK's own
25
+ * behaviour in that case is to WARN on stderr, construct anyway, and fail on
26
+ * the first call, which reads like a network problem rather than a missing
27
+ * setting.
28
+ *
29
+ * ─── Why native, and not `openai({ baseURL })` ──────────────────────
30
+ *
31
+ * Google publishes an OpenAI-compatible endpoint, and it does work — for about
32
+ * an hour. It authenticates with an OAuth access token that expires and has no
33
+ * refresh home in `OpenAIProviderOptions`; its `tools.function.parameters` is
34
+ * **OpenAPI**, not JSON Schema, so `$ref` / `oneOf` / `additionalProperties`
35
+ * diverge silently; unsupported parameters are ignored rather than refused; and
36
+ * its documented response carries no cached- or reasoning-token counts. This
37
+ * adapter exists because every one of those is answerable on the native SDK:
38
+ * ADC refreshes itself, tools go over as JSON Schema untranslated
39
+ * (`parametersJsonSchema`), a forced single tool is expressible, and
40
+ * `usageMetadata` reports cached and thinking tokens as separate numbers.
41
+ *
42
+ * ─── Limitations (stated, not discovered) ───────────────────────────
43
+ *
44
+ * • Multi-modal input/output NOT supported — `LLMMessage.content` is `string`,
45
+ * so this adapter sends and reads text parts only. Inline data, files and
46
+ * generated images are out of scope for the port as it stands.
47
+ * • **Thought summaries are not requested.** `usage.thinking` is reported
48
+ * honestly from `thoughtsTokenCount`, and `req.thinking.budget` is threaded
49
+ * to `thinkingConfig.thinkingBudget` — but `includeThoughts` is deliberately
50
+ * left unset, so no `rawThinking` is produced. Gemini's thought parts carry a
51
+ * `thoughtSignature` that has to be echoed byte-exact on the next turn, and
52
+ * there is no Gemini `ThinkingHandler` in this release to normalize and
53
+ * round-trip them. Asking for content nothing can carry would be a leak, not
54
+ * a feature. `thinkingConfig.thinkingLevel` has no field on `LLMRequest` and
55
+ * is likewise not sent.
56
+ * • `responseJsonSchema` (native structured output) is NOT exposed; use
57
+ * `.outputSchema(...)`, which goes over as a forced tool — a shape this
58
+ * adapter DOES carry.
59
+ * • Grounding tools (Google Search, code execution, URL context, MCP servers)
60
+ * are not exposed. `tools` carries function declarations only.
61
+ */
62
+ import type { LLMCallHooks, LLMChunk, LLMProvider, LLMRequest, LLMResponse, WireRole } from '../types.js';
63
+ import { type GoogleGenAIConnectionOptions } from './googleGenAI.js';
64
+ /** One `parts[]` entry. Only the members this adapter reads or writes. */
65
+ export interface GeminiPart {
66
+ readonly text?: string;
67
+ /** `true` on a thought-summary part. Never joined into visible content. */
68
+ readonly thought?: boolean;
69
+ readonly functionCall?: {
70
+ readonly id?: string;
71
+ readonly name?: string;
72
+ readonly args?: Record<string, unknown>;
73
+ };
74
+ readonly functionResponse?: {
75
+ readonly id?: string;
76
+ readonly name?: string;
77
+ readonly response?: Record<string, unknown>;
78
+ };
79
+ }
80
+ /** One conversation turn. Gemini's assistant role is spelled `'model'`. */
81
+ export interface GeminiContent {
82
+ readonly role: 'user' | 'model';
83
+ readonly parts: readonly GeminiPart[];
84
+ }
85
+ /** A `FunctionDeclaration`, JSON-Schema flavour. */
86
+ export interface GeminiFunctionDeclaration {
87
+ readonly name: string;
88
+ readonly description: string;
89
+ /**
90
+ * JSON Schema, passed through UNCHANGED. The sibling `parameters` field
91
+ * takes OpenAPI instead and is never set here — sending both is what makes
92
+ * an adapter's tool schemas quietly disagree with the ones it was given.
93
+ */
94
+ readonly parametersJsonSchema: Record<string, unknown>;
95
+ }
96
+ export interface GeminiGenerateConfig {
97
+ systemInstruction?: string;
98
+ temperature?: number;
99
+ maxOutputTokens?: number;
100
+ stopSequences?: string[];
101
+ abortSignal?: AbortSignal;
102
+ tools?: {
103
+ functionDeclarations: GeminiFunctionDeclaration[];
104
+ }[];
105
+ toolConfig?: {
106
+ functionCallingConfig: {
107
+ mode: 'AUTO' | 'ANY' | 'NONE';
108
+ allowedFunctionNames?: string[];
109
+ };
110
+ };
111
+ thinkingConfig?: {
112
+ thinkingBudget: number;
113
+ };
114
+ }
115
+ export interface GeminiGenerateParams {
116
+ readonly model: string;
117
+ readonly contents: readonly GeminiContent[];
118
+ readonly config?: GeminiGenerateConfig;
119
+ }
120
+ export interface GeminiUsageMetadata {
121
+ readonly promptTokenCount?: number;
122
+ readonly candidatesTokenCount?: number;
123
+ readonly cachedContentTokenCount?: number;
124
+ readonly thoughtsTokenCount?: number;
125
+ readonly totalTokenCount?: number;
126
+ }
127
+ export interface GeminiCandidate {
128
+ readonly content?: {
129
+ readonly parts?: readonly GeminiPart[];
130
+ };
131
+ readonly finishReason?: string;
132
+ }
133
+ export interface GeminiGenerateResponse {
134
+ readonly candidates?: readonly GeminiCandidate[];
135
+ readonly usageMetadata?: GeminiUsageMetadata;
136
+ readonly responseId?: string;
137
+ }
138
+ /**
139
+ * The `models` namespace, narrowed to the two operations this adapter
140
+ * dispatches.
141
+ *
142
+ * `countTokens` is deliberately ABSENT. It exists on the real namespace and it
143
+ * would be an easy way to fill in a usage number the wire did not report —
144
+ * which is precisely why it is not here. A count we asked for separately is not
145
+ * what the call was billed for; see the streaming note on `stream()`.
146
+ */
147
+ export interface GeminiModelsLike {
148
+ generateContent(params: GeminiGenerateParams): Promise<GeminiGenerateResponse>;
149
+ /** Note the double await: the SDK returns a PROMISE of an async generator. */
150
+ generateContentStream(params: GeminiGenerateParams): Promise<AsyncIterable<GeminiGenerateResponse>>;
151
+ }
152
+ /** What `new GoogleGenAI(...)` gives us, narrowed to what we use. */
153
+ export interface GeminiClientLike {
154
+ readonly models: GeminiModelsLike;
155
+ }
156
+ export interface GeminiProviderOptions extends GoogleGenAIConnectionOptions {
157
+ /**
158
+ * Default model used when `LLMRequest.model` is `'gemini'` (the shorthand).
159
+ * A request naming a full model id wins.
160
+ */
161
+ readonly defaultModel?: string;
162
+ /** Default `maxOutputTokens` when the request doesn't set it. Optional. */
163
+ readonly defaultMaxTokens?: number;
164
+ /** @internal Pre-built client for testing. Skips the SDK import entirely. */
165
+ readonly _client?: GeminiClientLike;
166
+ }
167
+ /**
168
+ * Build an `LLMProvider` backed by Gemini — on Vertex or on the Gemini API.
169
+ *
170
+ * @example Vertex (Application Default Credentials)
171
+ * ```ts
172
+ * import { Agent } from 'agentfootprint';
173
+ * import { gemini } from 'agentfootprint/providers';
174
+ *
175
+ * const agent = Agent.create({
176
+ * provider: gemini({ project: 'my-project', location: 'us-central1' }),
177
+ * model: 'gemini',
178
+ * })
179
+ * .tool(weatherTool)
180
+ * .build();
181
+ * ```
182
+ *
183
+ * @example Gemini API (one key, no cloud project)
184
+ * ```ts
185
+ * const provider = gemini({ apiKey: process.env.GEMINI_API_KEY });
186
+ * ```
187
+ *
188
+ * @throws at construction when neither a project nor an API key is resolvable,
189
+ * and when `@google/genai` is not installed.
190
+ */
191
+ export declare function gemini(options?: GeminiProviderOptions): LLMProvider;
192
+ /**
193
+ * Class form for consumers who prefer `new GeminiProvider(...)` over the
194
+ * `gemini(...)` factory. Identical behavior; trivial wrapper.
195
+ */
196
+ export declare class GeminiProvider implements LLMProvider {
197
+ readonly name = "gemini";
198
+ readonly carriesInMessages: readonly WireRole[];
199
+ readonly carriesForcedToolChoice = true;
200
+ private readonly inner;
201
+ constructor(options?: GeminiProviderOptions);
202
+ complete(req: LLMRequest, hooks?: LLMCallHooks): Promise<LLMResponse>;
203
+ stream(req: LLMRequest, hooks?: LLMCallHooks): AsyncIterable<LLMChunk>;
204
+ }