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
30 changes: 17 additions & 13 deletions ts/packages/actionGrammar/src/grammarMatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,19 +256,17 @@ function nextNonSeparatorIndex(request: string, index: number) {
return match === null ? index : index + match[0].length;
}

function finalizeMatch(
state: MatchState,
request: string,
results: GrammarMatchResult[],
) {
// Finalize the state to make capture the last wildcard if any
// and make sure there are any trailing un-matched non-separator characters.
function finalizeState(state: MatchState, request: string) {
if (state.pendingWildcard !== undefined) {
const value = getWildcardStr(
request,
state.pendingWildcard.start,
request.length,
);
if (value === undefined) {
return;
return false;
}
state.index = request.length;
addValueWithId(state, state.pendingWildcard.valueId, value, true);
Expand All @@ -282,13 +280,24 @@ function finalizeMatch(
nonSepIndex,
)}`,
);
return;
return false;
}

debugMatch(
`Consume trailing separators at ${state.index} to ${request.length}}`,
);
}
return true;
}

function finalizeMatch(
state: MatchState,
request: string,
results: GrammarMatchResult[],
) {
if (!finalizeState(state, request)) {
return;
}
debugMatch(
`Matched at end of input. Matched ids: ${JSON.stringify(state.valueIds)}, values: ${JSON.stringify(state.values)}'`,
);
Expand Down Expand Up @@ -640,12 +649,7 @@ function partialMatchRules(
`Start state ${state.name}{${state.partIndex}}: @${state.index}`,
);
if (!matchState(state, request, pending)) {
const nonSepIndex = nextNonSeparatorIndex(request, state.index);
if (nonSepIndex !== request.length) {
// There are not matched non-separator characters left
debugCompletion(
` Rejecting completion at ${state.name} with non-separator text at ${nonSepIndex}`,
);
if (!finalizeState(state, request)) {
continue;
}
const nextPart = state.rule.parts[state.partIndex];
Expand Down
31 changes: 25 additions & 6 deletions ts/packages/agents/player/src/agent/playerGrammar.agr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
| <PlayCommand>
@ <Pause> = pause ((the)? music)? -> { actionName: "pause" }
@ <Resume> = resume ((the)? music)? -> { actionName: "resume" }
@ <PlayCommand> = <PlayTrackNumberCommand>
@ <PlayCommand> = <PlayTrackNumberCommand> | <PlaySpecificTrack>
@ <PlayTrackNumberCommand> =
play (the)? $(n:<Ordinal>) (<Item>)? -> {
actionName: "playFromCurrentTrackList",
Expand All @@ -26,16 +26,35 @@
trackNumber: $(n)
}
}
@ <Item> = one | track | song | cut

@ <Item> = one | cut | <TrackTerm>
@ <TrackTerm> = track | song

@ <Cardinal> =
one -> 1
$(x:number)
| one -> 1
| two -> 2
| three -> 3
| four -> 4
@ <Ordinal> =


@ <Ordinal> =
first -> 1
| second -> 2
| third -> 3
| troisiemme -> 3
| fourth -> 4

| fourth -> 4

@ <TrackPhrase> = ((the)? <TrackTerm>)? $(trackName:<TrackName>)
| $(trackName:<TrackName>) <TrackTerm>
@ <PlaySpecificTrack> = play $(trackName:<TrackPhrase>) -> { actionName: "playTrack", parameters: { trackName: $(trackName) } }
| play $(trackName:<TrackPhrase>) by $(artist:<ArtistName>) -> { actionName: "playTrack", parameters: { trackName: $(trackName), artists: [$(artist)] } }
| play $(trackName:<TrackPhrase>) from (the)? album $(albumName:<AlbumName>) -> { actionName: "playTrack", parameters: { trackName: $(trackName), albumName: $(albumName) } }
| play $(trackName:<TrackPhrase>) by $(artist:<ArtistName>) from (the)? album $(albumName:<AlbumName>) -> { actionName: "playTrack", parameters: { trackName: $(trackName), artists: [$(artist)], albumName: $(albumName) } }

// TODO: wire up entity names
@ <TrackName> = $(x:string)
@ <ArtistName> = $(x:string)
@ <AlbumName> = $(x:string)


30 changes: 21 additions & 9 deletions ts/packages/shell/test/testHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,10 @@ export async function sendUserRequestFast(prompt: string, page: Page) {
page.keyboard.down("Enter");
}

async function getAgentMessageLocators(page: Page): Promise<Locator[]> {
return page.locator(".chat-message-agent .chat-message-content").all();
}

/**
* Submits a user request to the system via the chat input box and then waits for the first available response
* NOTE: If your expected response changes or you invoke multi-action flow you should be calling
Expand All @@ -241,9 +245,7 @@ export async function sendUserRequestAndWaitForResponse(
prompt: string,
page: Page,
): Promise<string> {
const locators: Locator[] = await page
.locator(".chat-message-agent .chat-message-content")
.all();
const locators = await getAgentMessageLocators(page);

// send the user request
await sendUserRequest(prompt, page);
Expand All @@ -264,9 +266,7 @@ export async function sendUserRequestAndWaitForCompletion(
prompt: string,
page: Page,
): Promise<string> {
const locators: Locator[] = await page
.locator(".chat-message-agent .chat-message-content")
.all();
const locators = await getAgentMessageLocators(page);

// send the user request
await sendUserRequest(prompt, page);
Expand Down Expand Up @@ -415,8 +415,17 @@ export async function runTestCallback(
}
}

export async function getAllAgentMessages(page: Page): Promise<string[]> {
const locators = await getAgentMessageLocators(page);
return (
await Promise.all(
locators.map((locator) => locator.innerText()).reverse(),
)
).filter((msg) => msg.length > 0);
}

/**
* Encapsulates the supplied method within a startup and shutdown of teh
* Encapsulates the supplied method within a startup and shutdown of the
* shell. Test code executes between them.
*/
export async function testUserRequest(
Expand All @@ -434,11 +443,14 @@ export async function testUserRequest(
userRequests[i],
mainWindow,
);

// verify expected result
expect(
msg,
`Chat agent didn't respond with the expected message. Request: '${userRequests[i]}', Response: '${expectedResponses[i]}'`,
[
`Chat agent didn't respond with the expected message. Request: '${userRequests[i]}', Response: '${expectedResponses[i]}'`,
`All response so far:`,
...(await getAllAgentMessages(mainWindow)),
].join("\n"),
).toBe(expectedResponses[i]);
}
});
Expand Down
Loading