Skip to content

Commit

Permalink
preparing for node v23 (#1051)
Browse files Browse the repository at this point in the history
* preparing for nodev23

* cleanup import

* test: 🔍 update schema type checks in tests
  • Loading branch information
pelikhan authored Jan 24, 2025
1 parent 2c17717 commit 6a66726
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 16 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20, 22]
node-version: [20, 22, 23]
steps:
- uses: actions/checkout@v4
with:
Expand Down
4 changes: 4 additions & 0 deletions docs/src/content/docs/reference/scripts/schemas.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ $`Use ${schema} for the JSON schema.`

Use `JSONSchema.infer` to generate a JSON schema from a JSON object.

```js
const schema = await JSONSchema.infer(data)
```

## Validation

When a JSON/YAML payload is generated with the schema identifier,
Expand Down
6 changes: 4 additions & 2 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"@octokit/rest": "^21.0.2",
"dockerode": "^4.0.4",
"es-toolkit": "^1.31.0",
"json-schema-generator": "^2.0.6",
"fluent-ffmpeg": "^2.1.3",
"gpt-tokenizer": "^2.8.1",
"html-to-text": "^9.0.5",
Expand Down Expand Up @@ -94,6 +95,7 @@
"devDependencies": {
"@types/diff": "^6.0.0",
"@types/dockerode": "^3.3.32",
"@types/json-schema-generator": "^2.0.3",
"@types/fs-extra": "^11.0.4",
"@types/memorystream": "^0.3.4",
"@types/node": "^22.10.7",
Expand Down Expand Up @@ -123,9 +125,9 @@
"compile:runtime:code": "tsc src/runtime.ts --skipLibCheck --outDir built --target es2020 --moduleResolution node --module esnext --removeComments true",
"compile:runtime": "yarn compile:runtime:declarations && yarn compile:runtime:code && mv built/runtime.js built/runtime.mjs",
"compile:api": "esbuild src/api.ts --outfile=built/api.mjs",
"compile:cli": "esbuild src/main.ts --metafile=./esbuild.meta.json --bundle --platform=node --target=node20 --outfile=built/genaiscript.cjs --external:tsx --external:esbuild --external:get-tsconfig --external:resolve-pkg-maps --external:dockerode --external:pdfjs-dist --external:web-tree-sitter --external:tree-sitter-wasms --external:promptfoo --external:typescript --external:@lvce-editor/ripgrep --external:gpt-3-encoder --external:mammoth --external:xlsx --external:mathjs --external:@azure/identity --external:gpt-tokenizer --external:playwright --external:@inquirer/prompts --external:jimp --external:turndown --external:turndown-plugin-gfm --external:vectra --external:tabletojson --external:html-to-text --external:@octokit/rest --external:@octokit/plugin-throttling --external:@octokit/plugin-retry --external:@octokit/plugin-paginate-rest --external:skia-canvas --external:@huggingface/transformers --external:@modelcontextprotocol/sdk --external:@anthropic-ai/sdk --external:@anthropic-ai/bedrock-sdk --external:es-toolkit --external:zod --external:zod-to-json-schema --external:fluent-ffmpeg && node ../../scripts/patch-cli.mjs",
"compile:cli": "esbuild src/main.ts --metafile=./esbuild.meta.json --bundle --platform=node --target=node20 --outfile=built/genaiscript.cjs --external:tsx --external:esbuild --external:get-tsconfig --external:resolve-pkg-maps --external:dockerode --external:pdfjs-dist --external:web-tree-sitter --external:tree-sitter-wasms --external:promptfoo --external:typescript --external:@lvce-editor/ripgrep --external:gpt-3-encoder --external:mammoth --external:xlsx --external:mathjs --external:@azure/identity --external:gpt-tokenizer --external:playwright --external:@inquirer/prompts --external:jimp --external:turndown --external:turndown-plugin-gfm --external:vectra --external:tabletojson --external:html-to-text --external:@octokit/rest --external:@octokit/plugin-throttling --external:@octokit/plugin-retry --external:@octokit/plugin-paginate-rest --external:skia-canvas --external:@huggingface/transformers --external:@modelcontextprotocol/sdk --external:@anthropic-ai/sdk --external:@anthropic-ai/bedrock-sdk --external:es-toolkit --external:zod --external:zod-to-json-schema --external:fluent-ffmpeg --external:json-schema-generator && node ../../scripts/patch-cli.mjs",
"compile": "yarn compile:api && yarn compile:runtime && yarn compile:cli",
"compile-debug": "esbuild src/main.ts --sourcemap --metafile=./esbuild.meta.json --bundle --platform=node --target=node20 --outfile=built/genaiscript.cjs --external:tsx --external:esbuild --external:get-tsconfig --external:resolve-pkg-maps --external:dockerode --external:pdfjs-dist --external:web-tree-sitter --external:tree-sitter-wasms --external:promptfoo --external:typescript --external:@lvce-editor/ripgrep --external:gpt-3-encoder --external:mammoth --external:xlsx --external:mathjs --external:@azure/identity --external:gpt-tokenizer --external:playwright --external:@inquirer/prompts --external:jimp --external:turndown --external:turndown-plugin-gfm --external:vectra --external:tabletojson --external:html-to-text --external:@octokit/rest --external:@octokit/plugin-throttling --external:@octokit/plugin-retry --external:@octokit/plugin-paginate-rest --external:skia-canvas --external:@huggingface/transformers --external:@modelcontextprotocol/sdk --external:@anthropic-ai/sdk --external:@anthropic-ai/bedrock-sdk --external:es-toolkit --external:zod --external:zod-to-json-schema --external:fluent-ffmpeg",
"compile-debug": "esbuild src/main.ts --sourcemap --metafile=./esbuild.meta.json --bundle --platform=node --target=node20 --outfile=built/genaiscript.cjs --external:tsx --external:esbuild --external:get-tsconfig --external:resolve-pkg-maps --external:dockerode --external:pdfjs-dist --external:web-tree-sitter --external:tree-sitter-wasms --external:promptfoo --external:typescript --external:@lvce-editor/ripgrep --external:gpt-3-encoder --external:mammoth --external:xlsx --external:mathjs --external:@azure/identity --external:gpt-tokenizer --external:playwright --external:@inquirer/prompts --external:jimp --external:turndown --external:turndown-plugin-gfm --external:vectra --external:tabletojson --external:html-to-text --external:@octokit/rest --external:@octokit/plugin-throttling --external:@octokit/plugin-retry --external:@octokit/plugin-paginate-rest --external:skia-canvas --external:@huggingface/transformers --external:@modelcontextprotocol/sdk --external:@anthropic-ai/sdk --external:@anthropic-ai/bedrock-sdk --external:es-toolkit --external:zod --external:zod-to-json-schema --external:fluent-ffmpeg --external:json-schema-generator",
"postcompile": "node built/genaiscript.cjs info help > ../../docs/src/content/docs/reference/cli/commands.md",
"vis:treemap": "npx --yes esbuild-visualizer --metadata esbuild.meta.json --filename esbuild.treemap.html",
"vis:network": "npx --yes esbuild-visualizer --metadata esbuild.meta.json --filename esbuild.network.html --template network",
Expand Down
5 changes: 1 addition & 4 deletions packages/core/src/anthropic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@ import { HttpsProxyAgent } from "https-proxy-agent"
import { MarkdownTrace } from "./trace"
import { createFetch, FetchType } from "./fetch"
import { JSONLLMTryParse } from "./json5"
import {
LanguageModelConfiguration,
LanguageModelInfo,
} from "./server/messages"
import { LanguageModelConfiguration } from "./server/messages"
import { deleteUndefinedValues } from "./cleaners"

const convertFinishReason = (
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/llms.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Model } from "@anthropic-ai/sdk/resources/index.mjs"
import { LARGE_MODEL_ID, SMALL_MODEL_ID, VISION_MODEL_ID } from "./constants"
import { ModelConfiguration, ModelConfigurations } from "./host"
import LLMS from "./llms.json"
Expand Down
109 changes: 105 additions & 4 deletions packages/core/src/schema.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { describe, test } from "node:test"
import assert from "node:assert/strict"
import { JSONSchemaStringifyToTypeScript, toStrictJSONSchema } from "./schema"
import {
JSONSchemaInfer,
JSONSchemaStringify,
JSONSchemaStringifyToTypeScript,
toStrictJSONSchema,
validateJSONWithSchema,
validateSchema,
} from "./schema"

describe("schema", () => {
test("cities", () => {
Expand Down Expand Up @@ -32,9 +39,9 @@ describe("schema", () => {
},
{
type: "number",
}
]
}
},
],
},
},
required: ["name", "population", "url"],
},
Expand Down Expand Up @@ -124,3 +131,97 @@ of the city.`,
assert.strictEqual(res.additionalProperties, false)
})
})

test("validateSchema", async () => {
const schema: JSONSchema = {
type: "object",
properties: {
name: { type: "string" },
age: { type: "number" },
},
required: ["name"],
}

const result = await validateSchema(schema)
assert.strictEqual(result, true)
})

test("validateJSONWithSchema - valid object", () => {
const schema: JSONSchema = {
type: "object",
properties: {
name: { type: "string" },
age: { type: "number" },
},
required: ["name"],
}

const object = { name: "John", age: 30 }
const result = validateJSONWithSchema(object, schema)
assert.strictEqual(result.pathValid, true)
assert.strictEqual(result.schemaError, undefined)
})

test("validateJSONWithSchema - invalid object", () => {
const schema: JSONSchema = {
type: "object",
properties: {
name: { type: "string" },
age: { type: "number" },
},
required: ["name"],
}

const object = { age: 30 }
const result = validateJSONWithSchema(object, schema)
assert.strictEqual(result.pathValid, false)
assert.ok(result.schemaError)
})

test("JSONSchemaStringify", () => {
const schema: JSONSchema = {
type: "object",
properties: {
name: { type: "string" },
age: { type: "number" },
},
required: ["name"],
}

const result = JSONSchemaStringify(schema)
assert.strictEqual(
result,
JSON.stringify(
{
$schema: "http://json-schema.org/draft-07/schema#",
...schema,
},
null,
2
)
)
})

test("toStrictJSONSchema", () => {
const schema: JSONSchema = {
type: "object",
properties: {
name: { type: "string" },
age: { type: "number" },
},
required: ["name"],
}

const result = toStrictJSONSchema(schema)
assert.deepStrictEqual(result.required, ["name", "age"])
assert.deepStrictEqual(result.properties["name"].type, "string")
assert.deepStrictEqual(result.properties["age"].type, ["number", "null"])
assert.strictEqual(result.additionalProperties, false)
})

test("JSONSchemaInfer", async () => {
const obj = { name: "John", age: 30 }
const schema = await JSONSchemaInfer(obj)
assert.strictEqual(schema.type, "object")
assert.deepStrictEqual(schema.required, ["name", "age"])
})
5 changes: 3 additions & 2 deletions packages/core/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import Ajv from "ajv"
import { YAMLParse } from "./yaml"
import { errorMessage } from "./error"
import { promptParametersSchemaToJSONSchema } from "./parameters"
import jsonToSchema from "json-schema-generator"

/**
* Check if an object is a JSON Schema
Expand Down Expand Up @@ -346,7 +345,9 @@ export function toStrictJSONSchema(
return clone
}

export function JSONSchemaInfer(obj: any): JSONSchema {

export async function JSONSchemaInfer(obj: any): Promise<JSONSchema> {
const { default: jsonToSchema } = await import("json-schema-generator")
const schema = jsonToSchema(obj)
return schema as JSONSchema
}
2 changes: 1 addition & 1 deletion packages/core/src/types/prompt_template.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2043,7 +2043,7 @@ interface JSONSchemaUtilities {
* Infers a JSON schema from an object
* @param obj
*/
infer(obj: any): JSONSchema
infer(obj: any): Promise<JSONSchema>
}

interface HTMLTableToJSONOptions {
Expand Down
2 changes: 1 addition & 1 deletion packages/sample/genaisrc/groq.genai.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1206,7 +1206,7 @@ const json = `[
}
]`
const query = "filter to keep completed tasks and userid 2"
const schema = JSONSchema.infer(JSON.parse(json))
const schema = await JSONSchema.infer(JSON.parse(json))

const res = await runPrompt(
(ctx) => {
Expand Down
11 changes: 11 additions & 0 deletions packages/sample/genaisrc/jsonschema.genai.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
script({ model: "small", tests: {} })
const a = {
a: 1,
b: ["abc", "def"],
c: {
d: 2,
},
}
const schema = await JSONSchema.infer(a)
if (!schema) throw new Error("Failed to infer schema")
console.log(schema)

0 comments on commit 6a66726

Please sign in to comment.