diff --git a/ts/packages/actionGrammar/README.AUTOGEN.md b/ts/packages/actionGrammar/README.AUTOGEN.md index d8ab51d2d..77a377601 100644 --- a/ts/packages/actionGrammar/README.AUTOGEN.md +++ b/ts/packages/actionGrammar/README.AUTOGEN.md @@ -3,7 +3,7 @@ - + # @typeagent/action-grammar — AI-generated documentation @@ -12,13 +12,13 @@ ## Overview -The `@typeagent/action-grammar` package is a TypeScript library that provides the grammar engine for the TypeAgent framework. It enables the parsing, compilation, and matching of natural language input against grammar rules defined in `.agr` files. These rules allow the conversion of user input, such as natural language commands, into structured JSON action objects that can be processed by agents. +The `@typeagent/action-grammar` package is a TypeScript library that provides a grammar engine for the TypeAgent framework. It enables the parsing, compilation, and matching of natural language input against grammar rules defined in `.agr` files. These rules allow user utterances to be converted into structured JSON action objects, which can then be processed by other components in the TypeAgent ecosystem. -This package is a core component of the TypeAgent ecosystem and is used by several other packages, including `@typeagent/core`, `@typeagent/action-grammar-compiler`, and `agent-cli`. +This package is a core dependency for several other TypeAgent packages, such as `@typeagent/core`, `@typeagent/action-grammar-compiler`, and `agent-cli`. It supports both rule-based and machine learning-assisted approaches to grammar generation and matching, making it a versatile tool for natural language understanding. ## What it does -The primary purpose of this package is to process natural language input and match it against predefined grammar rules to generate structured actions. These actions are represented as JSON objects, which can be consumed by other components in the TypeAgent ecosystem. For example: +The primary purpose of `@typeagent/action-grammar` is to process natural language input and match it against predefined grammar rules to generate structured actions. These actions are represented as JSON objects, such as: ```json { @@ -34,7 +34,7 @@ The primary purpose of this package is to process natural language input and mat 1. **Grammar Parsing**: - - Parses `.agr` files, which are written in a custom domain-specific language (DSL) for defining natural language grammar rules. + - Parses `.agr` files written in a custom domain-specific language (DSL) for defining natural language grammar rules. - The DSL supports constructs such as literals, wildcards, alternation, optionals, repetition, rule references, imports, and entity declarations. - The `parseGrammarRules` function converts `.agr` files into an Abstract Syntax Tree (AST). @@ -58,8 +58,12 @@ The primary purpose of this package is to process natural language input and mat - Supports runtime loading and caching of grammar rules, enabling dynamic updates to the grammar. 6. **Grammar Generation**: + - Includes tools for generating grammar rules from schemas and examples using large language models (LLMs) like Claude. +7. **Collision Analysis**: + - Provides utilities for detecting and resolving overlaps between grammar rules. + ## Setup To use the `@typeagent/action-grammar` package, follow these steps: @@ -170,6 +174,7 @@ External: `@anthropic-ai/claude-agent-sdk`, `debug`, `dotenv`, `regexp.escape` ### Used by +- [@typeagent/action-browser](../../tools/actionBrowser/README.md) - [@typeagent/action-grammar-compiler](../../packages/actionGrammarCompiler/README.md) - [@typeagent/core](../../packages/typeagent-core/README.md) - [agent-cache](../../packages/cache/README.md) @@ -179,7 +184,7 @@ External: `@anthropic-ai/claude-agent-sdk`, `debug`, `dotenv`, `regexp.escape` - [default-agent-provider](../../packages/defaultAgentProvider/README.md) - grammar-tools-cli - grammar-tools-core -- [snips-bench](../../examples/snipsBench/README.md) +- _…and 1 more workspace consumers._ ### Files of interest @@ -197,6 +202,6 @@ External: `@anthropic-ai/claude-agent-sdk`, `debug`, `dotenv`, `regexp.escape` --- -_Auto-generated against commit `defc71271dc68db47e0d376be7aa9f755da0ac91` on `2026-07-14T08:47:00.044Z` by `docs-generate.yml`. Links validated at that commit; the working tree may have drifted by up to 24h. Re-run `pnpm --filter @typeagent/action-grammar docs:verify-links` to spot-check._ +_Auto-generated against commit `d71a4baa2697f70bb62c315e67827ecc1ef19e9f` on `2026-07-22T16:16:20.408Z` by `docs-generate.yml`. Links validated at that commit; the working tree may have drifted by up to 24h. Re-run `pnpm --filter @typeagent/action-grammar docs:verify-links` to spot-check._ diff --git a/ts/packages/actionGrammar/src/grammarRuleParser.ts b/ts/packages/actionGrammar/src/grammarRuleParser.ts index a9cfd36ff..385237d0c 100644 --- a/ts/packages/actionGrammar/src/grammarRuleParser.ts +++ b/ts/packages/actionGrammar/src/grammarRuleParser.ts @@ -266,8 +266,9 @@ export type ValueNode = | VariableValueNode | ValueExprNode; -// Parser-time value node types: compiled base types augmented with comment fields. -// The compiler strips these before storing into GrammarRule (see grammarCompiler.ts). +// Parser-time value node types: compiled base types augmented with source-formatting +// metadata. The compiler strips these before storing into GrammarRule (see +// grammarCompiler.ts). // // leadingComments: comments before the value (e.g. after ":" or "["). // trailingComments: comments after the value but before the trailing "," or "]"/"}" delimiter. @@ -289,6 +290,7 @@ type VariableValueNode = CompiledVariableValueNode & { export type ObjectProperty = { type: "property"; key: string; + keyQuoted?: true | undefined; value: ValueNode | null; // null = shorthand: { x } means { x: x } leadingComments?: Comment[] | undefined; trailingComments?: Comment[] | undefined; @@ -1004,6 +1006,7 @@ class GrammarRuleParser implements ValueExprParserContext { obj.push({ type: "property", key: id, + ...(isStringLiteral ? { keyQuoted: true as const } : {}), value: v, leadingComments: pendingLeading, }); diff --git a/ts/packages/actionGrammar/src/grammarRuleWriter.ts b/ts/packages/actionGrammar/src/grammarRuleWriter.ts index aeb592af8..be89a5ec8 100644 --- a/ts/packages/actionGrammar/src/grammarRuleWriter.ts +++ b/ts/packages/actionGrammar/src/grammarRuleWriter.ts @@ -78,7 +78,7 @@ export type GrammarWriterOptions = { // This applies at two levels: // a. Between distinct Expr elements (variables, rule refs, groups, // and multi-word string tokens treated as units). -// b. Within a single multi-word string token: individual words are +// b. Within a single multi-word string token, individual words are // also wrapped at the same continuation column when needed. // // IR NODE TYPES: @@ -1088,7 +1088,10 @@ function writeValueNode( } else if (elem.value === null) { result.write(elem.key); } else { - result.write(`${elem.key}: `); + const key = elem.keyQuoted + ? JSON.stringify(elem.key) + : elem.key; + result.write(`${key}: `); writeValueNode( result, elem.value, diff --git a/ts/packages/actionGrammar/test/grammarRuleParser.spec.ts b/ts/packages/actionGrammar/test/grammarRuleParser.spec.ts index f4dc08998..f1ae971ad 100644 --- a/ts/packages/actionGrammar/test/grammarRuleParser.spec.ts +++ b/ts/packages/actionGrammar/test/grammarRuleParser.spec.ts @@ -416,11 +416,13 @@ describe("Grammar Rule Parser", () => { { type: "property", key: "type", + keyQuoted: true, value: { type: "literal", value: "greeting" }, }, { type: "property", key: "count", + keyQuoted: true, value: { type: "literal", value: 1 }, }, ], @@ -438,11 +440,13 @@ describe("Grammar Rule Parser", () => { { type: "property", key: "type", + keyQuoted: true, value: { type: "literal", value: "greeting" }, }, { type: "property", key: "count", + keyQuoted: true, value: { type: "literal", value: 1 }, }, ], diff --git a/ts/packages/actionGrammar/test/grammarRuleWriter.spec.ts b/ts/packages/actionGrammar/test/grammarRuleWriter.spec.ts index 0d68b5567..c1df411d2 100644 --- a/ts/packages/actionGrammar/test/grammarRuleWriter.spec.ts +++ b/ts/packages/actionGrammar/test/grammarRuleWriter.spec.ts @@ -311,6 +311,16 @@ describe("Grammar Rule Writer", () => { it("with object value", () => { validateRoundTrip(` = hello -> { b: true, n: 12, s: "string" };`); }); + it("preserves quoted object property names", () => { + const grammar = + ` = hello -> ` + + `{ "display-name": 1, "title": 2, role: 3 };`; + + expect(writeGrammarRules(parseGrammarRules("test", grammar))).toBe( + `${grammar}\n`, + ); + validateRoundTrip(grammar); + }); it("with object spread value", () => { validateRoundTrip( ` = hello $(x:) -> { ...x, extra: 1 };\n = world -> { a: 2 };`,