Skip to content

Commit

Permalink
docs: document JSON schema grammar support
Browse files Browse the repository at this point in the history
  • Loading branch information
giladgd committed Oct 11, 2023
1 parent f0c534f commit ac981b3
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 5 deletions.
60 changes: 57 additions & 3 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,20 @@ function getApiReferenceSidebar(): typeof typedocSidebar {
}

function orderApiReferenceSidebar(sidebar: typeof typedocSidebar): typeof typedocSidebar {
orderClasses(sidebar);
orderTypes(sidebar);

return sidebar;
}

function orderClasses(sidebar: typeof typedocSidebar) {
const baseChatPromptWrapper = "ChatPromptWrapper";
const chatPromptWrapperItems: DefaultTheme.SidebarItem[] = [];

const classes = sidebar.find((item) => item.text === "Classes");

if (classes == null || !(classes.items instanceof Array))
return sidebar;
return;

(classes.items as DefaultTheme.SidebarItem[]).unshift({
text: "Chat wrappers",
Expand Down Expand Up @@ -222,7 +229,54 @@ function orderApiReferenceSidebar(sidebar: typeof typedocSidebar): typeof typedo

return aIndex - bIndex;
});

return sidebar;
}

function orderTypes(sidebar: typeof typedocSidebar) {
const types = sidebar.find((item) => item.text === "Types");

if (types == null || !(types.items instanceof Array))
return;

function groupGbnfJsonSchema() {
if (types == null || !(types.items instanceof Array))
return;

const gbnfJsonSchemaItemTitle = "GbnfJsonSchema";
const gbnfItemsPrefix = "GbnfJson";
const gbnfJsonSchemaItems: DefaultTheme.SidebarItem[] = [];

const gbnfJsonSchemaItem = types.items
.find((item) => item.text === gbnfJsonSchemaItemTitle) as DefaultTheme.SidebarItem | null;

if (gbnfJsonSchemaItem == null)
return;

gbnfJsonSchemaItem.collapsed = true;
gbnfJsonSchemaItem.items = gbnfJsonSchemaItems;

for (const item of types.items.slice()) {
if (item.text === gbnfJsonSchemaItemTitle || !item.text.startsWith(gbnfItemsPrefix))
continue;

types.items.splice(types.items.indexOf(item), 1);
gbnfJsonSchemaItems.push(item);
}
}

function moveCollapseItemsToTheEnd() {
if (types == null || !(types.items instanceof Array))
return;

types.items.sort((a, b) => {
if (a.collapsed && !b.collapsed)
return 1;
if (!a.collapsed && b.collapsed)
return -1;

return 0;
});
}

groupGbnfJsonSchema();
moveCollapseItemsToTheEnd();
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* Chat with a model using a chat wrapper
* Use the CLI to chat with a model without writing any code
* Up-to-date with the latest version of `llama.cpp`. Download and compile the latest release with a single CLI command.
* Force a model to generate output in a parseable format, like JSON
* Force a model to generate output in a parseable format, like JSON, or even force it to follow a specific JSON schema

## [Documentation](https://withcatai.github.io/node-llama-cpp/)
* [Getting started guide](https://withcatai.github.io/node-llama-cpp/guide/)
Expand Down
44 changes: 44 additions & 0 deletions docs/guide/grammar.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,50 @@ console.log("AI: " + a2);
console.log(JSON.parse(a2));
```

## Using a JSON schema grammar
The [`LlamaGrammar.getForJsonSchema(<schema>)`](/api/classes/LlamaGrammar#getforjsonschema) creates a GBNF grammar based on the [JSON schema](https://json-schema.org/learn/getting-started-step-by-step) you provide, and then returns a [`LlamaGrammar`](/api/classes/LlamaGrammar).

It only supports a small subset of the JSON schema spec, but it's enough to generate useful JSON objects using a text generation model.

To see what subset of the JSON schema spec is supported, see the [`GbnfJsonSchema` type](/api/type-aliases/GbnfJsonSchema).

```typescript
import {fileURLToPath} from "url";
import path from "path";
import {LlamaModel, LlamaJsonSchemaGrammar, LlamaContext, LlamaChatSession} from "node-llama-cpp";

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const model = new LlamaModel({
modelPath: path.join(__dirname, "models", "codellama-13b.Q3_K_M.gguf")
})
const grammar = new LlamaJsonSchemaGrammar({
"type": "object",
"properties": {
"responseMessage": {
"type": "string"
},
"requestPositivityScoreFromOneToTen": {
"type": "number"
}
}
} as const);
const context = new LlamaContext({
model
});
const session = new LlamaChatSession({context});


const q1 = 'How are you doing?';
console.log("User: " + q1);

const a1 = await session.prompt(q1, {grammar, maxTokens: context.getContextSize()});
console.log("AI: " + a1);

const parsedA1 = grammar.parse(a1);
console.log(parsedA1.responseMessage, parsedA1.requestPositivityScoreFromOneToTen);
```

## Creating your own grammar
To create your own grammar, read the [GBNF guide](https://github.com/ggerganov/llama.cpp/blob/f5fe98d11bdf9e7797bcfb05c0c3601ffc4b9d26/grammars/README.md) to create a GBNF grammar file.

Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ features:
linkText: Learn more
- icon: <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24" fill="currentColor"><path d="M600-160q-17 0-28.5-11.5T560-200q0-17 11.5-28.5T600-240h80q17 0 28.5-11.5T720-280v-80q0-38 22-69t58-44v-14q-36-13-58-44t-22-69v-80q0-17-11.5-28.5T680-720h-80q-17 0-28.5-11.5T560-760q0-17 11.5-28.5T600-800h80q50 0 85 35t35 85v80q0 17 11.5 28.5T840-560t28.5 11.5Q880-537 880-520v80q0 17-11.5 28.5T840-400t-28.5 11.5Q800-377 800-360v80q0 50-35 85t-85 35h-80Zm-320 0q-50 0-85-35t-35-85v-80q0-17-11.5-28.5T120-400t-28.5-11.5Q80-423 80-440v-80q0-17 11.5-28.5T120-560t28.5-11.5Q160-583 160-600v-80q0-50 35-85t85-35h80q17 0 28.5 11.5T400-760q0 17-11.5 28.5T360-720h-80q-17 0-28.5 11.5T240-680v80q0 38-22 69t-58 44v14q36 13 58 44t22 69v80q0 17 11.5 28.5T280-240h80q17 0 28.5 11.5T400-200q0 17-11.5 28.5T360-160h-80Z"/></svg>
title: Output format
details: Force a model to generate output in a parseable format, like JSON
details: Force a model to generate output in a parseable format, like JSON, or even force it to follow a specific JSON schema
link: /guide/grammar
linkText: Learn more
---
Expand Down

0 comments on commit ac981b3

Please sign in to comment.