Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions ts/CONFIGURATION_AND_PERSISTENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,14 @@ The `dynamic.json` file contains all dynamically learned rules:
"schemas": {
"player": [
{
"grammarText": "@ <playTrack> = \"play\" $(trackName:string) \"by\" $(artistName:string)",
"grammarText": "<playTrack> = \"play\" $(trackName:string) \"by\" $(artistName:string)",
"timestamp": 1737850800000,
"sourceRequest": "play Bohemian Rhapsody by Queen",
"actionName": "playTrack",
"schemaName": "player"
},
{
"grammarText": "@ <pause> = \"pause\" (\"the\")? (\"music\")?",
"grammarText": "<pause> = \"pause\" (\"the\")? (\"music\")?",
"timestamp": 1737850900000,
"sourceRequest": "pause music",
"actionName": "pause",
Expand All @@ -187,7 +187,7 @@ The `dynamic.json` file contains all dynamically learned rules:
],
"calendar": [
{
"grammarText": "@ <scheduleEvent> = \"schedule\" $(event:string) $(time:CalendarTime)",
"grammarText": "<scheduleEvent> = \"schedule\" $(event:string) $(time:CalendarTime)",
"timestamp": 1737851000000,
"sourceRequest": "schedule meeting tomorrow at 2pm",
"actionName": "scheduleEvent",
Expand All @@ -212,7 +212,7 @@ await store.setAutoSave(true);

// Add a new rule (auto-saves if enabled)
await store.addRule({
grammarText: '@ <playTrack> = "play" $(track:string)',
grammarText: '<playTrack> = "play" $(track:string)',
schemaName: "player",
sourceRequest: "play music",
actionName: "playTrack",
Expand Down
22 changes: 15 additions & 7 deletions ts/extensions/agr-language/OVERVIEW.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ extensions/agr-language/

### 1. Syntax Elements Highlighted

- **Rule Definitions**: `@ <RuleName> = ...`
- **Rule Definitions**: `<RuleName> = ...;`

- `@` operator in keyword color
- Rule names in type color
- Assignment operator `=` highlighted
- Semicolon terminator `;` highlighted
- Multi-line rules supported (span from `=` to `;`)

- **Rule References**: `<RuleName>`

Expand Down Expand Up @@ -74,13 +75,19 @@ The grammar uses a repository-based pattern system:
"scopeName": "source.agr",
"patterns": [
{ "include": "#comments" },
{ "include": "#import-statement" },
{ "include": "#rule-definition" },
{ "include": "#action-object" }
],
"repository": {
"rule-definition": { ... },
"rule-definition": {
"begin": "^\\s*(<)([A-Za-z_][A-Za-z0-9_]*)(>)\\s*(=)",
"end": "(;)|(?=^\\s*<[A-Za-z_]|^\\s*//|^\\s*import\\b|\\z)",
"..."
},
"capture": { ... },
"rule-reference": { ... },
"import-statement": { ... },
...
}
}
Expand All @@ -90,9 +97,10 @@ The grammar uses a repository-based pattern system:

Uses standard TextMate scope names for compatibility with all VS Code themes:

- `keyword.operator.rule.agr` - Rule operators
- `entity.name.type.rule.agr` - Rule names
- `variable.parameter.capture.agr` - Capture variables
- `entity.name.type.rule.agr` - Rule names in definitions
- `entity.name.type.rule-reference.agr` - Rule names in references
- `punctuation.terminator.statement.agr` - Rule-ending semicolons
- `variable.other.agr` - Capture variable names
- `comment.line.double-slash.agr` - Comments
- `meta.embedded.block.javascript` - Embedded JS in action objects

Expand All @@ -116,7 +124,7 @@ Test file: [playerSchema.agr](../../packages/agents/player/src/agent/playerSchem
Expected highlighting:

- Green/gray comments
- Colorized rule names in `@ <Name>`
- Colorized rule names in `<Name> = ...;`
- Distinct colors for captures `$(name:Type)`
- Blue/purple keywords for operators
- JS syntax in action objects
Expand Down
4 changes: 2 additions & 2 deletions ts/extensions/agr-language/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Syntax highlighting for Action Grammar (.agr) files used in TypeAgent.

- Syntax highlighting for AGR grammar rules
- Comment support (`//`)
- Rule definition highlighting (`@ <RuleName> = ...`)
- Rule definition highlighting (`<RuleName> = ...;`)
- Rule reference highlighting (`<RuleName>`)
- Capture syntax highlighting (`$(name:Type)` and `$(name)`)
- Action object highlighting with embedded JavaScript syntax
Expand All @@ -21,7 +21,7 @@ Syntax highlighting for Action Grammar (.agr) files used in TypeAgent.
### Rule Definitions

```agr
@ <RuleName> = pattern1 | pattern2
<RuleName> = pattern1 | pattern2;
```

### Captures
Expand Down
58 changes: 29 additions & 29 deletions ts/extensions/agr-language/sample.agr
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@
// This file shows all the major syntax elements

// Import syntax
@import { Cardinal, TrackName, ArtistName } from "./base.agr"
@import * from "./shared.agr"
import { Cardinal, TrackName, ArtistName } from "./base.agr";
import * from "./shared.agr";

// Simple rule definition
@ <Start> = <Greeting> | <Command>
<Start> = <Greeting> | <Command>;

// Rule with captures and types
@ <Greeting> =
<Greeting> =
hello $(name:PersonName) -> {
actionName: "greet",
parameters: {
name
}
}
| hi there -> { actionName: "greet" }
| hi there -> { actionName: "greet" };

// Rule with optional elements
@ <Command> =
<Command> =
play (the)? $(track:TrackName)
by $(artist:ArtistName) -> {
actionName: "playTrack",
Expand All @@ -31,71 +31,71 @@
artists: [artist]
}
}
| pause (the)? music? -> { actionName: "pause" }
| pause (the)? music? -> { actionName: "pause" };

// Rule with multiple patterns
@ <Volume> =
<Volume> =
(turn | set) (the)? volume to $(level:number) -> {
actionName: "setVolume",
parameters: { level }
}
| volume up -> { actionName: "volumeUp" }
| volume down -> { actionName: "volumeDown" }
| volume down -> { actionName: "volumeDown" };

// Bare -> results (non-object): string literal, number, or variable reference
@ <PromptSpec> = (
<PromptSpec> = (
('ask me' | 'confirm' | 'please confirm') -> "true" |
("don't ask" | 'without asking' | 'skip') -> "false"
)
);

@ <FilterSpec> = (
<FilterSpec> = (
'by query' $(userQuery:string) -> userQuery |
'by category' $(category:string) -> category |
'all' -> "all"
)
);

// Numeric patterns
@ <Cardinal> =
<Cardinal> =
$(x:number)
| one -> 1
| two -> 2
| three -> 3
| four -> 4
| five -> 5
| five -> 5;

// String type references
@ <TrackName> = $(x:string)
@ <ArtistName> = $(x:string)
@ <PersonName> = $(x:string)
<TrackName> = $(x:string);
<ArtistName> = $(x:string);
<PersonName> = $(x:string);

// Complex nested rule
@ <PlayCommand> =
<PlayTrack> | <PlayAlbum> | <PlayArtist>
<PlayCommand> =
<PlayTrack> | <PlayAlbum> | <PlayArtist>;

@ <PlayTrack> =
<PlayTrack> =
play track $(n:<Cardinal>) -> {
actionName: "playTrackNumber",
parameters: {
trackNumber: n,
source: "current"
}
}
};

@ <PlayAlbum> =
<PlayAlbum> =
play (the)? album $(album:<AlbumName>) -> {
actionName: "playAlbum",
parameters: { albumName: album }
}
};

@ <PlayArtist> =
<PlayArtist> =
play music by $(artist:<ArtistName>) -> {
actionName: "playArtist",
parameters: { artistName: artist }
}
};

@ <AlbumName> = $(x:string)
<AlbumName> = $(x:string);

// Operators demonstration
@ <Operators> =
<Operators> =
one? two* three+ four // optional, zero-or-more, one-or-more
| (first | second | third) // alternation with grouping
| (first | second | third) // alternation with grouping;
28 changes: 16 additions & 12 deletions ts/extensions/agr-language/syntaxes/agr.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
"import-statement": {
"patterns": [
{
"comment": "Named import: @import { RuleA, RuleB } from './path.agr'",
"begin": "^\\s*(@)(import)\\b",
"end": "(?=$|//)",
"comment": "Named import: import { RuleA, RuleB } from './path.agr';",
"begin": "^\\s*(import)\\b",
"end": "(;)|(?=$|//)",
"beginCaptures": {
"1": { "name": "keyword.operator.rule.agr" },
"2": { "name": "keyword.control.import.agr" }
"1": { "name": "keyword.control.import.agr" }
},
"endCaptures": {
"1": { "name": "punctuation.terminator.statement.agr" }
},
"patterns": [
{
Expand All @@ -50,14 +52,16 @@
"rule-definition": {
"patterns": [
{
"begin": "^\\s*(@)\\s*(<)([A-Za-z_][A-Za-z0-9_]*)(>)\\s*(=)",
"end": "(?=^\\s*@|^\\s*//|\\z)",
"begin": "^\\s*(<)([A-Za-z_][A-Za-z0-9_]*)(>)\\s*(=)",
"end": "(;)|(?=^\\s*<[A-Za-z_]|^\\s*//|^\\s*import\\b|\\z)",
"beginCaptures": {
"1": { "name": "keyword.operator.rule.agr" },
"2": { "name": "punctuation.definition.rule-name.begin.agr" },
"3": { "name": "entity.name.type.rule.agr" },
"4": { "name": "punctuation.definition.rule-name.end.agr" },
"5": { "name": "keyword.operator.assignment.agr" }
"1": { "name": "punctuation.definition.rule-name.begin.agr" },
"2": { "name": "entity.name.type.rule.agr" },
"3": { "name": "punctuation.definition.rule-name.end.agr" },
"4": { "name": "keyword.operator.assignment.agr" }
},
"endCaptures": {
"1": { "name": "punctuation.terminator.statement.agr" }
},
"patterns": [{ "include": "#rule-body" }]
}
Expand Down
20 changes: 10 additions & 10 deletions ts/packages/actionGrammar/DYNAMIC_LOADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const baseNFA = compileGrammarToNFA(baseGrammar, "base");
const cache = new DynamicGrammarCache(baseGrammar, baseNFA);

// Add generated rule dynamically
const generatedRule = `@ <play> = play $(track:string) by $(artist:string)`;
const generatedRule = `<play> = play $(track:string) by $(artist:string);`;
const result = cache.addRules(generatedRule);

if (result.success) {
Expand Down Expand Up @@ -129,7 +129,7 @@ Before loading, the system validates that all referenced symbols are resolved:
const loader = new DynamicGrammarLoader();

// Rule references CalendarDate symbol
const rule = `@ <schedule> = schedule $(event:string) on $(date:CalendarDate)`;
const rule = `<schedule> = schedule $(event:string) on $(date:CalendarDate);`;

const result = loader.load(rule);

Expand Down Expand Up @@ -185,10 +185,10 @@ When multiple rules target the same action, they become alternatives:
const cache = new DynamicGrammarCache(baseGrammar, baseNFA);

// Add first play pattern
cache.addRules(`@ <play> = play $(track:string)`);
cache.addRules(`<play> = play $(track:string);`);

// Add second play pattern (alternative)
cache.addRules(`@ <play> = play $(track:string) by $(artist:string)`);
cache.addRules(`<play> = play $(track:string) by $(artist:string);`);

// Both patterns now work
const result1 = matchNFA(cache.getNFA(), ["play", "Song"]);
Expand All @@ -203,7 +203,7 @@ const result2 = matchNFA(cache.getNFA(), ["play", "Song", "by", "Artist"]);
### Parse Errors

```typescript
const result = cache.addRules(`@ <invalid> = this is not valid grammar`);
const result = cache.addRules(`<invalid> = this is not valid grammar;`);

if (!result.success) {
console.error("Parse errors:", result.errors);
Expand All @@ -215,7 +215,7 @@ if (!result.success) {

```typescript
const result = cache.addRules(
`@ <schedule> = schedule $(event:string) on $(date:UnknownType)`,
`<schedule> = schedule $(event:string) on $(date:UnknownType);`,
);

if (!result.success) {
Expand Down Expand Up @@ -274,10 +274,10 @@ const loader = new DynamicGrammarLoader();

// Load multiple rules at once
const agrText = `
@ <play> = play $(track:string)
@ <play> = play $(track:string) by $(artist:string)
@ <pause> = pause
@ <resume> = resume
<play> = play $(track:string);
<play> = play $(track:string) by $(artist:string);
<pause> = pause;
<resume> = resume;
`;

const result = loader.load(agrText);
Expand Down
Loading