Skip to content

Commit 4ec5a4f

Browse files
authored
docs: migrating from 0.5 guide (#1187)
1 parent fc58fad commit 4ec5a4f

File tree

1 file changed

+323
-0
lines changed

1 file changed

+323
-0
lines changed

‎docs/migrating-from-0.5.md‎

Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
# Migrating from 0.5
2+
3+
Genkit 0.9 introduces a number of breaking changes alongside feature enhancements that improve overall functionality. If you have been developing applications with Genkit 0.5, you will need to update your application code when you upgrade to the latest version. This guide outlines the most significant changes and offers steps to migrate your existing applications smoothly.
4+
5+
## 1. CLI Changes
6+
7+
The command-line interface (CLI) has undergone significant updates in Genkit 0.9. The command to start Genkit has changed, and the CLI has been separated into its own standalone package, which you now need to install separately.
8+
9+
To install the CLI:
10+
11+
```posix-terminal
12+
npm i -g genkit-cli
13+
```
14+
15+
**Old Command:**
16+
17+
```posix-terminal
18+
genkit start
19+
```
20+
21+
This command starts both the flow server and the Dev UI in a single command.
22+
23+
**New Commands:**
24+
25+
Now, you must start the dev UI and the flow servers as separate steps.
26+
27+
To start the dev UI:
28+
29+
```posix-terminal
30+
genkit ui:start
31+
```
32+
33+
Once the UI is running, start the flow server:
34+
35+
```posix-terminal
36+
GENKIT_ENV=dev tsx --watch path/to/index.ts
37+
```
38+
39+
Starting the flow server this way makes it easier for you to attach a debugger to your code. Be sure to set `GENKIT_ENV=dev` in your debugger’s startup configuration.
40+
41+
The Dev UI will interact directly with the flow server to figure out which flows are registered and allow you to invoke them directly with sample inputs.
42+
43+
## 2. Simplified packages and imports
44+
45+
Previously, the Genkit libraries were separated into several modules, which you needed to install and import individually. These modules have now been consolidated into a single import. In addition, the Zod module is now re-exported by Genkit.
46+
47+
**Old:**
48+
49+
```posix-terminal
50+
npm i @genkit-ai/core @genkit-ai/ai @genkit-ai/flow @genkit-ai/dotprompt
51+
```
52+
53+
**New:**
54+
55+
```posix-terminal
56+
npm i genkit
57+
```
58+
59+
**Old:**
60+
61+
```js
62+
import { … } from '@genkit-ai/ai';
63+
import { … } from '@genkit-ai/core';
64+
import { … } from '@genkit-ai/flow';
65+
import * as z from 'zod';
66+
```
67+
68+
**New:**
69+
70+
```js
71+
import { genkit, z } from 'genkit';
72+
```
73+
74+
Genkit plugins still must be installed and imported individually.
75+
76+
## 3. Configuring Genkit
77+
78+
Previously, initializing Genkit was done once globally by calling the `configureGenkit` function. Genkit resources (flows, tools, prompts, etc.) would all automatically be wired with this global configuration.
79+
80+
Genkit 0.9 introduces `Genkit` instances, each of which encapsulates a configuration. See the following examples:
81+
82+
**Old:**
83+
84+
```js
85+
import { configureGenkit } from '@genkit-ai/core';
86+
87+
configureGenkit({
88+
telemetry: {
89+
instrumentation: ...,
90+
logger: ...
91+
}
92+
});
93+
```
94+
95+
**New:**
96+
97+
```js
98+
import { genkit } from 'genkit';
99+
import { logger } from 'genkit/logging';
100+
import { enableFirebaseTelemetry } from '@genkit-ai/firebase';
101+
102+
logger.setLogLevel('debug');
103+
enableFirebaseTelemetry({...});
104+
105+
const ai = genkit({ ... });
106+
```
107+
108+
Let’s break it down:
109+
- `configureGenkit()` has been replaced with `genkit()`, and it returns a configured `Genkit` instance rather than setting up configurations globally.
110+
- The Genkit initialization function is now in the `genkit` package.
111+
- Logging and telemetry are still configured globally using their own explicit methods. These configurations apply uniformly across all `Genkit` instances.
112+
113+
## 4. Defining flows and starting the flow server explicitly
114+
115+
Now that you have a configured `Genkit` instance, you will need to define your flows. All core developer-facing API methods like `defineFlow`, `defineTool`, and `onFlow` are now invoked through this instance.
116+
117+
This is distinct from the previous way, where flows and tools were registered globally.
118+
119+
**Old:**
120+
121+
```js
122+
import { defineFlow, defineTool, onFlow } from '@genkit-ai/core';
123+
124+
defineFlow(...);
125+
defineTool(...);
126+
127+
onFlow(...);
128+
```
129+
130+
**New:**
131+
132+
```js
133+
// Define tools and flows
134+
const sampleFlow = ai.defineFlow(...);
135+
const sampleTool = ai.defineTool(...);
136+
137+
// onFlow now takes the Genkit instance as first argument
138+
// This registers the flow as a callable firebase function
139+
onFlow(ai, ...);
140+
141+
const flows = [ sampleFlow, ... ];
142+
// Start the flow server to make the registered flows callable over HTTP
143+
ai.startFlowServer({flows});
144+
```
145+
146+
As of now, all flows that you want to make available need to be explicitly registered in the `flows` array above.
147+
148+
## 5. Tools and Prompts must be statically defined
149+
150+
In earlier versions of Genkit, you could dynamically define tools and prompts at runtime, directly from within a flow.
151+
152+
In Genkit 0.9, this behavior is no longer allowed. Instead, you need to define all actions and flows outside of the flow’s execution (i.e. statically).
153+
154+
This change enforces a stricter separation of action definitions from execution.
155+
156+
If any of your code is defined dynamically, they need to be refactored. Otherwise, an error will be thrown at runtime when the flow is executed.
157+
158+
**❌ DON'T:**
159+
160+
```js
161+
const flow = defineFlow({...}, async (input) => {
162+
const tool = defineTool({...});
163+
await tool.call(...);
164+
});
165+
```
166+
167+
**✅ DO:**
168+
169+
```js
170+
const tool = ai.defineTool({...});
171+
172+
const flow = ai.defineFlow({...}, async (input) => {
173+
await tool.call(...);
174+
});
175+
```
176+
177+
## 6. New API for Streaming Flows
178+
179+
In Genkit 0.9, we have simplified the syntax for defining a streaming flow and invoking it.
180+
181+
First, `defineFlow` and `defineStreamingFlow` have been separated. If you have a flow that is meant to be streamed, you will have to update your code to define it via `defineStreamingFlow`.
182+
183+
Second, instead of calling separate `stream()` and `response()` functions, both stream and response are now values returned directly from the flow. This change simplifies flow streaming.
184+
185+
**Old:**
186+
187+
```js
188+
import { defineFlow, streamFlow } from '@genkit-ai/flow';
189+
190+
const myStreamingFlow = defineFlow(...);
191+
const { stream, output } = await streamFlow(myStreamingFlow, ...);
192+
193+
for await (const chunk of stream()) {
194+
console.log(chunk);
195+
}
196+
197+
console.log(await output());
198+
```
199+
200+
**New:**
201+
202+
```js
203+
const myStreamingFlow = ai.defineStreamingFlow(...);
204+
const { stream, response } = await myStreamingFlow(...);
205+
206+
for await (const chunk of stream) {
207+
console.log(chunk);
208+
}
209+
210+
console.log(await response);
211+
```
212+
213+
## 7. GenerateResponse class methods replaced with getter properties
214+
215+
Previously, you used to access the structured output or text of the response using class methods, like `output()` or `text()`.
216+
217+
In Genkit 0.9, those methods have been replaced by getter properties. This simplifies working with responses.
218+
219+
**Old:**
220+
221+
```js
222+
const response = await generate({ prompt: 'hi' });
223+
console.log(response.text());
224+
```
225+
226+
**New:**
227+
228+
```js
229+
const response = await ai.generate('hi');
230+
console.log(response.text);
231+
```
232+
The same applies to `output`:
233+
234+
**Old:**
235+
236+
```js
237+
console.log(response.output());
238+
```
239+
240+
**New:**
241+
242+
```js
243+
console.log(response.output);
244+
```
245+
246+
## 8. Candidate Generation Eliminated
247+
248+
Genkit 0.9 simplifies response handling by removing the `candidates` attribute. Previously, responses could contain multiple candidates, which you needed to handle explicitly. Now, only the first candidate is returned directly in a flat response.
249+
250+
Any code that accesses the candidates directly will not work anymore.
251+
252+
**Old:**
253+
254+
```js
255+
const response = await generate({
256+
messages: [ { role: 'user', content: ...} ]
257+
});
258+
console.log(response.candidates); // previously you could access candidates directly
259+
```
260+
261+
**New:**
262+
263+
```js
264+
const response = await ai.generate({
265+
messages: [ { role: 'user', content: ...} ]
266+
});
267+
console.log(response.message); // single candidate is returned directly in a flat response
268+
```
269+
270+
## 9. Generate API - Multi-Turn enhancements
271+
272+
For multi-turn conversations, the old `toHistory()` method has been replaced by `messages`, further simplifying how conversation history is handled.
273+
274+
**Old:**
275+
276+
```js
277+
const history = response.toHistory();
278+
```
279+
280+
**New:**
281+
282+
```js
283+
const response = await ai.generate({
284+
messages: [ { role: 'user', content: ...} ]
285+
});
286+
const history = response.messages;
287+
```
288+
289+
## 10. Streamlined Chat API
290+
291+
In Genkit 0.9, the Chat API has been redesigned for easier session management and interaction. Here’s how you can leverage it for both synchronous and streaming chat experiences:
292+
293+
```js
294+
import { genkit } from 'genkit';
295+
import { gemini15Flash, googleAI } from '@genkit-ai/googleai';
296+
297+
const ai = genkit({
298+
plugins: [googleAI()],
299+
model: gemini15Flash,
300+
});
301+
302+
const session = ai.createSession({ store: firestoreSessionStore() });
303+
const chat = await session.chat({ system: 'talk like a pirate' });
304+
305+
let response = await chat.send('hi, my name is Pavel');
306+
console.log(response.text()); // "hi Pavel, I'm llm"
307+
308+
// continue the conversation
309+
response = await chat.send("what's my name");
310+
console.log(response.text()); // "Pavel"
311+
312+
// can stream
313+
const { response, stream } = await chat.sendStream('bye');
314+
for await (const chunk of stream) {
315+
console.log(chunk.text());
316+
}
317+
console.log((await response).text());
318+
319+
// can load session from the store
320+
const prevSession = await ai.loadSession(session.id, { store });
321+
const prevChat = await prevSession.chat();
322+
await prevChat.send('bye');
323+
```

0 commit comments

Comments
 (0)