@gram-ai/create-function 0.1.1 → 0.2.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.
- package/dist/main.js +34 -4
- package/dist/main.js.map +1 -1
- package/gram-template-gram/NEXT_STEPS.txt +14 -0
- package/gram-template-gram/README.md +58 -0
- package/gram-template-gram/package.json +5 -2
- package/gram-template-gram/src/server.ts +44 -0
- package/package.json +2 -2
- package/src/main.ts +37 -6
package/dist/main.js
CHANGED
|
@@ -9,6 +9,25 @@ import pkg from "../package.json" with { type: "json" };
|
|
|
9
9
|
import { confirmOrClack, selectOrClack, textOrClack, yn, } from "./prompts/helpers.js";
|
|
10
10
|
const packageNameRE = /^(@?[a-z0-9-_]+\/)?[a-z0-9-_]+$/;
|
|
11
11
|
const knownPackageManagers = new Set(["npm", "yarn", "pnpm", "bun", "deno"]);
|
|
12
|
+
function printUsage(packageManager) {
|
|
13
|
+
console.log(`
|
|
14
|
+
Usage:
|
|
15
|
+
${packageManager} create @gram-ai/function [options]
|
|
16
|
+
|
|
17
|
+
Options:
|
|
18
|
+
--template <name> Template to use (gram, mcp)
|
|
19
|
+
--name <name> Project name
|
|
20
|
+
--dir <path> Directory to create project in
|
|
21
|
+
--git <yes|no> Initialize git repository
|
|
22
|
+
--install <yes|no> Install dependencies
|
|
23
|
+
-y, --yes Skip all prompts and use defaults
|
|
24
|
+
|
|
25
|
+
Examples:
|
|
26
|
+
${packageManager} create @gram-ai/function
|
|
27
|
+
${packageManager} create @gram-ai/function --template mcp --name ecommerce
|
|
28
|
+
${packageManager} create @gram-ai/function --yes --template gram
|
|
29
|
+
`);
|
|
30
|
+
}
|
|
12
31
|
async function init(argv) {
|
|
13
32
|
let packageManager = "npm";
|
|
14
33
|
let detectedPM = process.env["npm_config_user_agent"]?.split("/")[0] || "";
|
|
@@ -16,10 +35,14 @@ async function init(argv) {
|
|
|
16
35
|
packageManager = detectedPM;
|
|
17
36
|
}
|
|
18
37
|
const args = parse(argv, {
|
|
19
|
-
alias: { y: "yes" },
|
|
38
|
+
alias: { y: "yes", h: "help" },
|
|
20
39
|
string: ["template", "name", "dir", "git", "install"],
|
|
21
|
-
boolean: ["yes"],
|
|
40
|
+
boolean: ["yes", "help"],
|
|
22
41
|
});
|
|
42
|
+
if (args.help) {
|
|
43
|
+
printUsage(packageManager);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
23
46
|
const template = await selectOrClack({
|
|
24
47
|
message: "Pick a framework",
|
|
25
48
|
options: [
|
|
@@ -105,7 +128,7 @@ async function init(argv) {
|
|
|
105
128
|
await fs.cp(templateDir, dir, {
|
|
106
129
|
recursive: true,
|
|
107
130
|
filter: (src) => {
|
|
108
|
-
let banned = src.includes(".git");
|
|
131
|
+
let banned = src.includes(".git") || src.includes("NEXT_STEPS.txt");
|
|
109
132
|
if (isLocalDev) {
|
|
110
133
|
banned ||= src.includes("node_modules") || src.includes("dist");
|
|
111
134
|
}
|
|
@@ -148,7 +171,14 @@ async function init(argv) {
|
|
|
148
171
|
tlog.message(`Installing dependencies with ${packageManager}`);
|
|
149
172
|
await $ `cd ${dir} && ${packageManager} install`;
|
|
150
173
|
}
|
|
151
|
-
|
|
174
|
+
let successMessage = `All done! Run \`cd ${dir} && ${packageManager} run build\` to build your first Gram Function.`;
|
|
175
|
+
successMessage = await fs
|
|
176
|
+
.readFile(join(templateDir, "NEXT_STEPS.txt"), "utf-8")
|
|
177
|
+
.catch(() => successMessage);
|
|
178
|
+
successMessage = successMessage
|
|
179
|
+
.replaceAll("$PACKAGE_MANAGER", packageManager)
|
|
180
|
+
.replaceAll("$DIR", dir);
|
|
181
|
+
tlog.success(successMessage);
|
|
152
182
|
}
|
|
153
183
|
try {
|
|
154
184
|
await init(process.argv);
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,CAAC,EAAE,MAAM,IAAI,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAExD,OAAO,EACL,cAAc,EACd,aAAa,EACb,WAAW,EACX,EAAE,GACH,MAAM,sBAAsB,CAAC;AAE9B,MAAM,aAAa,GAAG,iCAAiC,CAAC;AAExD,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;AAE7E,KAAK,UAAU,IAAI,CAAC,IAAc;IAChC,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,IAAI,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3E,IAAI,oBAAoB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACzC,cAAc,GAAG,UAAU,CAAC;IAC9B,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE;QACvB,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE;
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
All done! Jump in with `cd $DIR`.
|
|
2
|
+
|
|
3
|
+
Some next steps:
|
|
4
|
+
|
|
5
|
+
- Build your function with `$PACKAGE_MANAGER run build` and deploy it with the Gram CLI: https://www.speakeasy.com/docs/gram/command-line/installation.
|
|
6
|
+
|
|
7
|
+
- Run the provided Hono server to simulate tool calls over HTTP with `$PACKAGE_MANAGER run dev` and:
|
|
8
|
+
|
|
9
|
+
curl \
|
|
10
|
+
--data '{"name": "greet", "input": {"name": "Friend"}}' \
|
|
11
|
+
-H "Content-Type: application/json" \
|
|
12
|
+
http://localhost:3000/tool-call
|
|
13
|
+
|
|
14
|
+
Have fun 🚀
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Hello from Gram Functions!
|
|
2
|
+
|
|
3
|
+
This project builds and deploys [Gram Functions](https://getgram.ai) using a
|
|
4
|
+
tiny TypeScript framework that looks like this:
|
|
5
|
+
|
|
6
|
+
```ts
|
|
7
|
+
import { Gram } from "@gram-ai/functions";
|
|
8
|
+
import * as z from "zod/mini";
|
|
9
|
+
|
|
10
|
+
const gram = new Gram().tool({
|
|
11
|
+
name: "greet",
|
|
12
|
+
description: "Greet someone special",
|
|
13
|
+
inputSchema: { name: z.string() },
|
|
14
|
+
async execute(ctx, input) {
|
|
15
|
+
return ctx.json({ message: `Hello, ${input.name}!` });
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export default gram;
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Gram Functions are tools for LLMs and MCP servers that can do arbitrary tasks
|
|
23
|
+
such as fetching data from APIs, performing calculations, or interacting with
|
|
24
|
+
hosted databases.
|
|
25
|
+
|
|
26
|
+
## Getting Started
|
|
27
|
+
|
|
28
|
+
To get started, install dependencies and run the development server:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pnpm install
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
To build a zip file that can be deployed to Gram, run:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm build
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If you want to poke at the tools you've built during local development, you can
|
|
41
|
+
start a Hono server with:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pnpm dev
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Now you can simulate tool calls with:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
curl \
|
|
51
|
+
--data '{"name": "greet", "input": {"name": "Georges"}}' \
|
|
52
|
+
-H "Content-Type: application/json" \
|
|
53
|
+
http://localhost:3000/tool-call
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## What next?
|
|
57
|
+
|
|
58
|
+
To learn more about using the framework, check out [CONTRIBUTING.md](./CONTRIBUTING.md)
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"node": ">=22.18.0"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
|
+
"dev": "node ./src/server.ts",
|
|
22
23
|
"lint": "tsc --noEmit",
|
|
23
24
|
"build": "node ./src/build.ts",
|
|
24
25
|
"prebuild": "tsc -p tsconfig.json",
|
|
@@ -29,7 +30,9 @@
|
|
|
29
30
|
"zod": "^4"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
|
-
"
|
|
33
|
-
"@types/node": "22.x"
|
|
33
|
+
"@hono/node-server": "^1.19.5",
|
|
34
|
+
"@types/node": "22.x",
|
|
35
|
+
"hono": "^4",
|
|
36
|
+
"typescript": "^5"
|
|
34
37
|
}
|
|
35
38
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { serve } from "@hono/node-server";
|
|
2
|
+
import { Hono } from "hono";
|
|
3
|
+
import gram from "./functions.ts";
|
|
4
|
+
|
|
5
|
+
const app = new Hono();
|
|
6
|
+
|
|
7
|
+
app.post("/tool-call", async (c) => {
|
|
8
|
+
const req = await c.req.json();
|
|
9
|
+
return await gram.handleToolCall(req, {
|
|
10
|
+
signal: AbortSignal.timeout(1 * 60 * 1000),
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
app.get("/manifest", async () => {
|
|
15
|
+
const manifest = gram.manifest();
|
|
16
|
+
return new Response(JSON.stringify(manifest, null, 2), {
|
|
17
|
+
headers: { "Content-Type": "application/json" },
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export function startServer(port: number = 3000) {
|
|
22
|
+
const server = serve({ fetch: app.fetch, port }, (info) => {
|
|
23
|
+
console.log(`Listening on http://localhost:${info.port}`);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const onClose = () => {
|
|
27
|
+
console.log("Shutting down server...");
|
|
28
|
+
server.close((err) => {
|
|
29
|
+
if (err) {
|
|
30
|
+
console.error(err);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
process.exit(0);
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
process.on("SIGINT", onClose);
|
|
37
|
+
process.on("SIGTERM", onClose);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (import.meta.main) {
|
|
41
|
+
startServer();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default app;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gram-ai/create-function",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"description": "Build AI tools and deploy them to getgram.ai",
|
|
6
6
|
"keywords": [],
|
|
7
7
|
"homepage": "https://github.com/speakeasy-api/gram",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"prettier": "^3.6.2",
|
|
39
39
|
"typescript": "5.9.2",
|
|
40
40
|
"zod": "^3.25.76",
|
|
41
|
-
"@gram-ai/functions": "^0.
|
|
41
|
+
"@gram-ai/functions": "^0.2.0"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build": "tsc --noEmit false"
|
package/src/main.ts
CHANGED
|
@@ -18,6 +18,26 @@ const packageNameRE = /^(@?[a-z0-9-_]+\/)?[a-z0-9-_]+$/;
|
|
|
18
18
|
|
|
19
19
|
const knownPackageManagers = new Set(["npm", "yarn", "pnpm", "bun", "deno"]);
|
|
20
20
|
|
|
21
|
+
function printUsage(packageManager: string): void {
|
|
22
|
+
console.log(`
|
|
23
|
+
Usage:
|
|
24
|
+
${packageManager} create @gram-ai/function [options]
|
|
25
|
+
|
|
26
|
+
Options:
|
|
27
|
+
--template <name> Template to use (gram, mcp)
|
|
28
|
+
--name <name> Project name
|
|
29
|
+
--dir <path> Directory to create project in
|
|
30
|
+
--git <yes|no> Initialize git repository
|
|
31
|
+
--install <yes|no> Install dependencies
|
|
32
|
+
-y, --yes Skip all prompts and use defaults
|
|
33
|
+
|
|
34
|
+
Examples:
|
|
35
|
+
${packageManager} create @gram-ai/function
|
|
36
|
+
${packageManager} create @gram-ai/function --template mcp --name ecommerce
|
|
37
|
+
${packageManager} create @gram-ai/function --yes --template gram
|
|
38
|
+
`);
|
|
39
|
+
}
|
|
40
|
+
|
|
21
41
|
async function init(argv: string[]): Promise<void> {
|
|
22
42
|
let packageManager = "npm";
|
|
23
43
|
let detectedPM = process.env["npm_config_user_agent"]?.split("/")[0] || "";
|
|
@@ -26,11 +46,16 @@ async function init(argv: string[]): Promise<void> {
|
|
|
26
46
|
}
|
|
27
47
|
|
|
28
48
|
const args = parse(argv, {
|
|
29
|
-
alias: { y: "yes" },
|
|
49
|
+
alias: { y: "yes", h: "help" },
|
|
30
50
|
string: ["template", "name", "dir", "git", "install"],
|
|
31
|
-
boolean: ["yes"],
|
|
51
|
+
boolean: ["yes", "help"],
|
|
32
52
|
});
|
|
33
53
|
|
|
54
|
+
if (args.help) {
|
|
55
|
+
printUsage(packageManager);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
34
59
|
const template = await selectOrClack<string>({
|
|
35
60
|
message: "Pick a framework",
|
|
36
61
|
options: [
|
|
@@ -125,7 +150,7 @@ async function init(argv: string[]): Promise<void> {
|
|
|
125
150
|
await fs.cp(templateDir, dir, {
|
|
126
151
|
recursive: true,
|
|
127
152
|
filter: (src) => {
|
|
128
|
-
let banned = src.includes(".git");
|
|
153
|
+
let banned = src.includes(".git") || src.includes("NEXT_STEPS.txt");
|
|
129
154
|
if (isLocalDev) {
|
|
130
155
|
banned ||= src.includes("node_modules") || src.includes("dist");
|
|
131
156
|
}
|
|
@@ -178,9 +203,15 @@ async function init(argv: string[]): Promise<void> {
|
|
|
178
203
|
await $`cd ${dir} && ${packageManager} install`;
|
|
179
204
|
}
|
|
180
205
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
206
|
+
let successMessage = `All done! Run \`cd ${dir} && ${packageManager} run build\` to build your first Gram Function.`;
|
|
207
|
+
successMessage = await fs
|
|
208
|
+
.readFile(join(templateDir, "NEXT_STEPS.txt"), "utf-8")
|
|
209
|
+
.catch(() => successMessage);
|
|
210
|
+
successMessage = successMessage
|
|
211
|
+
.replaceAll("$PACKAGE_MANAGER", packageManager)
|
|
212
|
+
.replaceAll("$DIR", dir);
|
|
213
|
+
|
|
214
|
+
tlog.success(successMessage);
|
|
184
215
|
}
|
|
185
216
|
|
|
186
217
|
try {
|