@@ -32,6 +32,10 @@ import {
3232 AppAgentStateConfig ,
3333 appAgentStateKeys ,
3434} from "./appAgentStateConfig.js" ;
35+ import { GrammarStore } from "../../../cache/dist/cache/types.js" ;
36+ import { getPackageFilePath } from "../utils/getPackageFilePath.js" ;
37+ import fs from "node:fs" ;
38+ import { Grammar , grammarFromJson } from "action-grammar" ;
3539
3640const debug = registerDebug ( "typeagent:dispatcher:agents" ) ;
3741const debugError = registerDebug ( "typeagent:dispatcher:agents:error" ) ;
@@ -91,6 +95,32 @@ export const alwaysEnabledAgents = {
9195 commands : [ "system" ] ,
9296} ;
9397
98+ function loadGrammar ( actionConfig : ActionConfig ) : Grammar | undefined {
99+ if ( actionConfig . grammarFile === undefined ) {
100+ return undefined ;
101+ }
102+
103+ let source : string ;
104+ if ( typeof actionConfig . grammarFile === "string" ) {
105+ const fullPath = getPackageFilePath ( actionConfig . grammarFile ) ;
106+ source = fs . readFileSync ( fullPath , "utf-8" ) ;
107+ const isActionGrammar = actionConfig . grammarFile . endsWith ( ".ag.json" ) ;
108+ if ( ! isActionGrammar ) {
109+ throw new Error (
110+ `Unsupported grammar file extension: ${ actionConfig . grammarFile } ` ,
111+ ) ;
112+ }
113+ } else {
114+ if ( actionConfig . grammarFile . format !== "ag" ) {
115+ throw new Error (
116+ `Unsupported grammar file extension: ${ actionConfig . grammarFile } ` ,
117+ ) ;
118+ }
119+ source = actionConfig . grammarFile . content ;
120+ }
121+ return grammarFromJson ( JSON . parse ( source ) ) ;
122+ }
123+
94124export class AppAgentManager implements ActionConfigProvider {
95125 private readonly agents = new Map < string , AppAgentRecord > ( ) ;
96126 private readonly actionConfigs = new Map < string , ActionConfig > ( ) ;
@@ -237,6 +267,7 @@ export class AppAgentManager implements ActionConfigProvider {
237267
238268 public async addProvider (
239269 provider : AppAgentProvider ,
270+ actionGrammarStore : GrammarStore | undefined ,
240271 actionEmbeddingCache ?: EmbeddingCache ,
241272 ) {
242273 const semanticMapP : Promise < void > [ ] = [ ] ;
@@ -246,6 +277,8 @@ export class AppAgentManager implements ActionConfigProvider {
246277 name ,
247278 manifest ,
248279 semanticMapP ,
280+
281+ actionGrammarStore ,
249282 provider ,
250283 actionEmbeddingCache ,
251284 ) ;
@@ -259,6 +292,7 @@ export class AppAgentManager implements ActionConfigProvider {
259292 appAgentName : string ,
260293 manifest : AppAgentManifest ,
261294 semanticMapP : Promise < void > [ ] ,
295+ actionGrammarStore : GrammarStore | undefined ,
262296 provider ?: AppAgentProvider ,
263297 actionEmbeddingCache ?: EmbeddingCache ,
264298 ) {
@@ -289,6 +323,17 @@ export class AppAgentManager implements ActionConfigProvider {
289323 ) ,
290324 ) ;
291325 }
326+
327+ if ( actionGrammarStore ) {
328+ try {
329+ const g = loadGrammar ( config ) ;
330+ if ( g ) {
331+ actionGrammarStore . addGrammar ( schemaName , g ) ;
332+ }
333+ } catch {
334+ // REVIEW: Ignore errors for now.
335+ }
336+ }
292337 } catch ( e : any ) {
293338 schemaErrors . set ( schemaName , e ) ;
294339 }
@@ -321,6 +366,7 @@ export class AppAgentManager implements ActionConfigProvider {
321366 appAgentName : string ,
322367 manifest : AppAgentManifest ,
323368 appAgent : AppAgent ,
369+ actionGrammarStore ?: GrammarStore ,
324370 ) {
325371 if ( this . agents . has ( appAgentName ) ) {
326372 throw new Error ( `App agent '${ appAgentName } ' already exists` ) ;
@@ -332,6 +378,7 @@ export class AppAgentManager implements ActionConfigProvider {
332378 appAgentName ,
333379 manifest ,
334380 semanticMapP ,
381+ actionGrammarStore ,
335382 ) ;
336383 record . appAgent = appAgent ;
337384
@@ -340,7 +387,7 @@ export class AppAgentManager implements ActionConfigProvider {
340387 debug ( "Finish action embeddings" ) ;
341388 }
342389
343- private cleanupAgent ( appAgentName : string ) {
390+ private cleanupAgent ( appAgentName : string , grammarStore ?: GrammarStore ) {
344391 for ( const [ schemaName , config ] of this . actionConfigs ) {
345392 if ( getAppAgentName ( schemaName ) !== appAgentName ) {
346393 continue ;
@@ -351,13 +398,19 @@ export class AppAgentManager implements ActionConfigProvider {
351398 if ( config . transient ) {
352399 delete this . transientAgents [ schemaName ] ;
353400 }
401+ if ( grammarStore ) {
402+ grammarStore . removeGrammar ( schemaName ) ;
403+ }
354404 }
355405 }
356406
357- public async removeAgent ( appAgentName : string ) {
407+ public async removeAgent (
408+ appAgentName : string ,
409+ grammarStore ?: GrammarStore ,
410+ ) {
358411 const record = this . getRecord ( appAgentName ) ;
359412 this . agents . delete ( appAgentName ) ;
360- this . cleanupAgent ( appAgentName ) ;
413+ this . cleanupAgent ( appAgentName , grammarStore ) ;
361414
362415 await this . closeSessionContext ( record ) ;
363416 if ( record . appAgent !== undefined ) {
0 commit comments