Skip to content

Commit 51142b8

Browse files
committed
Sync open source content 🐝 (from 5e3b3d4fddb56538112664c521101d6265133313)
1 parent 577fc01 commit 51142b8

File tree

1 file changed

+131
-1
lines changed

1 file changed

+131
-1
lines changed

docs/gram/gram-functions/functions-framework.mdx

Lines changed: 131 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,5 +163,135 @@ const gram = new Gram().tool({
163163
});
164164
```
165165

166+
## Composability
167+
168+
Gram instances can be composed together using the `.extend()` method, allowing tool definitions to be split across multiple files and modules. This pattern is similar to Hono's grouping pattern and helps organize larger codebases.
169+
170+
### Basic composition
171+
172+
Split tool definitions into separate modules and combine them:
173+
174+
```typescript filename="train.ts"
175+
import { Gram } from "@gram-ai/functions";
176+
import * as z from "zod/mini";
177+
178+
export const trainGram = new Gram({
179+
envSchema: {
180+
TRAIN_API_KEY: z.string().describe("API key for the train service"),
181+
},
182+
})
183+
.tool({
184+
name: "train_book",
185+
description: "Books a train ticket",
186+
inputSchema: { destination: z.string(), date: z.string() },
187+
async execute(ctx, input) {
188+
const apiKey = ctx.env.TRAIN_API_KEY;
189+
// Implementation here
190+
return ctx.json({ booked: true });
191+
},
192+
})
193+
.tool({
194+
name: "train_status",
195+
description: "Gets the status of a train",
196+
inputSchema: { trainId: z.string() },
197+
async execute(ctx, input) {
198+
// Implementation here
199+
return ctx.json({ status: "on time" });
200+
},
201+
});
202+
```
203+
204+
```typescript filename="flight.ts"
205+
import { Gram } from "@gram-ai/functions";
206+
import * as z from "zod/mini";
207+
208+
export const flightGram = new Gram({
209+
envSchema: {
210+
FLIGHT_API_KEY: z.string().describe("API key for the flight service"),
211+
},
212+
})
213+
.tool({
214+
name: "flight_book",
215+
description: "Books a flight ticket",
216+
inputSchema: { destination: z.string(), date: z.string() },
217+
async execute(ctx, input) {
218+
const apiKey = ctx.env.FLIGHT_API_KEY;
219+
// Implementation here
220+
return ctx.json({ booked: true });
221+
},
222+
})
223+
.tool({
224+
name: "flight_status",
225+
description: "Gets the status of a flight",
226+
inputSchema: { flightNumber: z.string() },
227+
async execute(ctx, input) {
228+
// Implementation here
229+
return ctx.json({ status: "departed" });
230+
},
231+
});
232+
```
233+
234+
```typescript filename="gram.ts"
235+
import { Gram } from "@gram-ai/functions";
236+
import { trainGram } from "./train";
237+
import { flightGram } from "./flight";
238+
239+
const gram = new Gram()
240+
.extend(trainGram)
241+
.extend(flightGram);
242+
243+
export default gram;
244+
```
245+
246+
### Environment schema merging
247+
248+
When composing Gram instances, environment schemas are automatically merged. Each module can define its own environment variables, and the final composed instance will validate all required variables:
249+
250+
```typescript
251+
// Each module defines its own environment requirements
252+
const weatherGram = new Gram({
253+
envSchema: {
254+
WEATHER_API_KEY: z.string(),
255+
},
256+
}).tool({
257+
name: "get_weather",
258+
inputSchema: { city: z.string() },
259+
async execute(ctx, input) {
260+
// Access environment variable from this module
261+
const apiKey = ctx.env.WEATHER_API_KEY;
262+
return ctx.json({ temperature: 72 });
263+
},
264+
});
265+
266+
const newsGram = new Gram({
267+
envSchema: {
268+
NEWS_API_KEY: z.string(),
269+
},
270+
}).tool({
271+
name: "get_news",
272+
inputSchema: { topic: z.string() },
273+
async execute(ctx, input) {
274+
// Access environment variable from this module
275+
const apiKey = ctx.env.NEWS_API_KEY;
276+
return ctx.json({ articles: [] });
277+
},
278+
});
279+
280+
// Composed instance requires both environment variables
281+
const gram = new Gram()
282+
.extend(weatherGram)
283+
.extend(newsGram);
284+
// Both WEATHER_API_KEY and NEWS_API_KEY must be provided
285+
```
286+
287+
### Benefits of composition
288+
289+
Composing Gram instances provides several advantages:
290+
291+
- **Modularity**: Organize related tools into separate files
292+
- **Reusability**: Share tool definitions across different Gram instances
293+
- **Maintainability**: Easier to manage large codebases with many tools
294+
- **Team collaboration**: Different team members can work on separate modules
295+
166296
## Next steps
167-
- [Build and deploy](/docs/gram/gram-functions/build-deploy)
297+
- [Build and deploy](/docs/gram/gram-functions/build-deploy)

0 commit comments

Comments
 (0)