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
48 changes: 36 additions & 12 deletions ts/packages/knowledgeProcessor/src/conversation/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
createKnowledgeStore,
createTextIndex,
} from "../knowledgeIndex.js";
import { Action } from "./knowledgeSchema.js";
import { Action, VerbTense } from "./knowledgeSchema.js";
import path from "path";
import { ActionFilter } from "./knowledgeSearchSchema.js";
import {
Expand Down Expand Up @@ -280,13 +280,25 @@ export async function createActionIndex<TSourceId = any>(
}

const names = await getNameIndex();
const [subjectToActionIds, objectToActionIds] = await Promise.all([
const [
subjectToActionIds,
objectToActionIds,
indirectToObjectIds,
verbToActionIds,
] = await Promise.all([
matchTerms(names, subjectIndex, filter.terms, options),
matchTerms(names, objectIndex, filter.terms, options),
matchTerms(names, indirectObjectIndex, filter.terms, options),
matchVerbTerms(filter.verbs, undefined, options),
]);
results.actionIds = [
...intersectMultiple(
intersectUnionMultiple(subjectToActionIds, objectToActionIds),
intersectUnionMultiple(
subjectToActionIds,
objectToActionIds,
indirectToObjectIds,
verbToActionIds,
),
itemsFromTemporalSequence(results.temporalSequence),
),
];
Expand Down Expand Up @@ -338,16 +350,11 @@ export async function createActionIndex<TSourceId = any>(
options: ActionSearchOptions,
): Promise<ActionId[] | undefined> {
if (filter.verbFilter && filter.verbFilter.verbs.length > 0) {
const verbOptions = options.verbSearchOptions ?? options;
const matches = await verbIndex.getNearest(
actionVerbsToString(
filter.verbFilter.verbs,
filter.verbFilter.verbTense,
),
verbOptions.maxMatches,
verbOptions.minScore,
return matchVerbTerms(
filter.verbFilter.verbs,
filter.verbFilter.verbTense,
options,
);
return matches;
}
return undefined;
}
Expand All @@ -366,6 +373,23 @@ export async function createActionIndex<TSourceId = any>(
return intersectUnionMultiple(...matches);
}

async function matchVerbTerms(
verbs: string[] | undefined,
verbTense: VerbTense | undefined,
options: ActionSearchOptions,
): Promise<ActionId[] | undefined> {
if (verbs && verbs.length > 0) {
const verbOptions = options.verbSearchOptions ?? options;
const matches = await verbIndex.getNearest(
actionVerbsToString(verbs, verbTense),
verbOptions.maxMatches,
verbOptions.minScore,
);
return matches;
}
return undefined;
}

async function matchTimeRange(timeRange: DateTimeRange | undefined) {
if (timeRange) {
return await actionStore.sequence.getEntriesInRange(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -703,16 +703,19 @@ export async function createConversation(
]);
const results = createSearchResponse<MessageId, TopicId, EntityId>();
for (const filter of filters) {
// Only search actions if (a) actions are enabled (b) we have an action filter
const topicResult = await topicIndex.searchTerms(
filter,
options.topic,
);
results.topics.push(topicResult);

const entityResult = await entityIndex.searchTerms(
filter,
options.entity,
);
results.entities.push(entityResult);

if (options.action) {
const actionResult = await actionIndex.searchTerms(
filter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@ import { DateTimeRange } from "./dateTimeSchema.js";
The message sequence, and any entities, actions and topics in each message are indexed.
*/

// Search indexes for following terms
// Search indexes for following "bag of words" terms
export type TermFilter = {
// action verb terms to look for
verbs?: string[];
// Terms are one of the following:
// Entity Terms:
// - the name of an entity or thing such as "Bach", "Great Gatsby", "frog" or "piano"
// - the *type* of the entity such as "speaker", "person", "artist", "animal", "object", "instrument", "school", "room", "museum", "food" etc.
// An entity can have multiple types; entity types should be single words
// - facets: specific, inherent, defining, or non-immediate facet of an entity such as "blue", "old", "famous", "sister", "aunt_of", "weight: 4 kg"
// Action Terms:
// - verbs
// - subject, object, indirectObject
// - subject, object and indirectObject associated with the verb
// verbs are not duplicated
terms: string[];
// Use only if request explicitly asks for time range
timeRange?: DateTimeRange | undefined; // in this time range
Expand Down