Skip to content

Commit f05a5f9

Browse files
authored
Parameter completion emoji in Schema Config (#1504)
Allow agent to specify the emoji for parameters in completions using the SchemaConfig file. Closes #1487
1 parent 5e1641e commit f05a5f9

File tree

17 files changed

+172
-95
lines changed

17 files changed

+172
-95
lines changed

ts/packages/actionSchema/src/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export {
1212
ParsedActionSchema,
1313
ActionSchemaObject,
1414
ActionSchemaUnion,
15+
SchemaObjectFields,
1516
} from "./type.js";
1617

1718
export { parseActionSchemaSource } from "./parser.js";
@@ -49,7 +50,12 @@ export {
4950
export { validateType } from "./validate.js";
5051

5152
// Schema Config
52-
export { SchemaConfig, ParamSpec, ActionParamSpecs } from "./schemaConfig.js";
53+
export {
54+
SchemaConfig,
55+
ParamSpec,
56+
ActionParamSpecs,
57+
CompletionEmojis,
58+
} from "./schemaConfig.js";
5359

5460
// Legacy (to be deprecated)
5561
export { NodeType, SchemaParser, ISymbol, SymbolNode } from "./schemaParser.js";

ts/packages/actionSchema/src/parser.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,17 @@ function checkActionSchema(
193193
}
194194
actionDefinition.paramSpecs = paramSpecs;
195195
}
196+
197+
const paramCompletionEmojis =
198+
schemaConfig?.paramCompletionEmojis?.[actionNameString];
199+
if (paramCompletionEmojis) {
200+
actionDefinition.paramCompletionEmojis = paramCompletionEmojis;
201+
}
202+
const entityCompletionEmojis =
203+
schemaConfig?.entityCompletionEmojis?.[actionNameString];
204+
if (entityCompletionEmojis) {
205+
actionDefinition.entityCompletionEmojis = entityCompletionEmojis;
206+
}
196207
return [actionNameString, actionDefinition];
197208
}
198209

ts/packages/actionSchema/src/schemaConfig.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@ export type ParamSpec =
1212
| "literal";
1313

1414
export type ActionParamSpecs = Record<string, ParamSpec> | false;
15+
export type CompletionEmojis = Record<string, string>; // Key is parameter/entity name, value is emoji string
1516
export type SchemaConfig = {
1617
// Key is the action name.
1718
// If the value is false, then explanation/caching is disabled.
1819
// Otherwise, the value is an object where the key is the parameter name, and the value the one of the ParamSpec above.
1920
paramSpec?: Record<string, ActionParamSpecs>;
2021

22+
paramCompletionEmojis?: Record<string, CompletionEmojis>; // Key is action name
23+
entityCompletionEmojis?: Record<string, CompletionEmojis>; // Key is entity type name
24+
2125
// separate the cache by action name
2226
actionNamespace?: boolean; // default to false
2327
};

ts/packages/actionSchema/src/type.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
import { ActionParamSpecs } from "./schemaConfig.js";
4+
import { ActionParamSpecs, CompletionEmojis } from "./schemaConfig.js";
55

66
export interface SchemaBase {
77
type:
@@ -130,7 +130,11 @@ export interface ActionSchemaObject extends SchemaTypeObject {
130130
export type ActionSchemaTypeDefinition = (
131131
| SchemaTypeInterfaceDefinition<ActionSchemaObject>
132132
| SchemaTypeAliasDefinition<ActionSchemaObject>
133-
) & { paramSpecs?: ActionParamSpecs };
133+
) & {
134+
paramSpecs?: ActionParamSpecs;
135+
paramCompletionEmojis?: CompletionEmojis;
136+
entityCompletionEmojis?: CompletionEmojis;
137+
};
134138

135139
export type ActionSchemaEntryTypeDefinition =
136140
| ActionSchemaTypeDefinition

ts/packages/agentSdk/src/command.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export type CompletionGroup = {
5353
name: string; // The group name for the completion
5454
completions: string[]; // The list of completions in the group
5555
needQuotes?: boolean; // If true, the completion should be quoted if it has spaces.
56-
emojiChar?: string; // Optional icon for the completion category
56+
emojiChar?: string | undefined; // Optional icon for the completion category
5757
};
5858

5959
export interface AppAgentCommandInterface {

ts/packages/agents/player/src/agent/playerSchema.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,23 @@
4040
"getFavorites": {
4141
"count": "number"
4242
}
43+
},
44+
"paramCompletionEmojis": {
45+
"playTrack": {
46+
"trackName": "🎶",
47+
"artists.*": "🎼"
48+
},
49+
"playAlbum": {
50+
"albumName": "💿",
51+
"artists.*": "🎼"
52+
},
53+
"playAlbumTrack": {
54+
"albumName": "💿",
55+
"trackName": "🎶",
56+
"artists.*": "🎼"
57+
},
58+
"playArtist": {
59+
"artist": "🎼"
60+
}
4361
}
4462
}

ts/packages/cli/src/commands/schema.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { composeTranslatorSchemas } from "common-utils";
66
import {
77
getAssistantSelectionSchemas,
88
getFullSchemaText,
9-
getActionSchema,
9+
tryGetActionSchema,
1010
getAllActionConfigProvider,
1111
} from "agent-dispatcher/internal";
1212
import { getInstanceDir } from "agent-dispatcher/helpers/data";
@@ -65,7 +65,7 @@ export default class Schema extends Command {
6565
const { args, flags } = await this.parse(Schema);
6666
if (!flags.assistant) {
6767
if (args.actionName) {
68-
const actionSchema = getActionSchema(
68+
const actionSchema = tryGetActionSchema(
6969
{
7070
schemaName: args.schemaName,
7171
actionName: args.actionName,

ts/packages/dispatcher/src/context/system/handlers/actionCommandHandler.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ import { CommandHandlerContext } from "../../commandHandlerContext.js";
1515
import { getParameterNames, validateAction } from "action-schema";
1616
import { executeActions } from "../../../execute/actionHandlers.js";
1717
import { FullAction, toExecutableActions } from "agent-cache";
18-
import { getActionSchema } from "../../../internal.js";
1918
import { DeepPartialUndefined, getObjectProperty } from "common-utils";
2019
import { getActionParamCompletion } from "../../../translation/requestCompletion.js";
20+
import { getActionSchema } from "../../../translation/actionSchemaUtils.js";
21+
import { tryGetActionSchema } from "../../../translation/actionSchemaFileCache.js";
2122

2223
export class ActionCommandHandler implements CommandHandler {
2324
public readonly description = "Execute an action";
@@ -50,14 +51,7 @@ export class ActionCommandHandler implements CommandHandler {
5051
throw new Error(`Invalid schema name ${schemaName}`);
5152
}
5253

53-
const actionSchema =
54-
actionSchemaFile.parsedActionSchema.actionSchemas.get(actionName);
55-
if (actionSchema === undefined) {
56-
throw new Error(
57-
`Invalid action name ${actionName} for schema ${schemaName}`,
58-
);
59-
}
60-
54+
const actionSchema = getActionSchema(actionSchemaFile, actionName);
6155
const action: AppAction = {
6256
schemaName: schemaName,
6357
actionName,
@@ -118,7 +112,7 @@ export class ActionCommandHandler implements CommandHandler {
118112
actionName: params.args?.actionName,
119113
parameters: params.flags?.parameters,
120114
};
121-
const actionInfo = getActionSchema(
115+
const actionInfo = tryGetActionSchema(
122116
action,
123117
systemContext.agents,
124118
);
@@ -156,10 +150,10 @@ export class ActionCommandHandler implements CommandHandler {
156150
name.substring("--parameters.".length),
157151
);
158152

159-
if (parameterCompletion && parameterCompletion.length > 0) {
153+
if (parameterCompletion) {
160154
completions.push({
161155
name,
162-
completions: parameterCompletion,
156+
...parameterCompletion,
163157
});
164158
}
165159

ts/packages/dispatcher/src/execute/actionHandlers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ import {
4242
isSwitchEnabled,
4343
translatePendingRequestAction,
4444
} from "../translation/translateRequest.js";
45-
import { getActionSchema } from "../internal.js";
4645
import { validateAction } from "action-schema";
4746
import {
4847
PendingAction,
@@ -55,6 +54,7 @@ import {
5554
addResultToMemory,
5655
} from "../context/memory.js";
5756
import { setActivityContext } from "./activityContext.js";
57+
import { tryGetActionSchema } from "../translation/actionSchemaFileCache.js";
5858

5959
const debugActions = registerDebug("typeagent:dispatcher:actions");
6060

@@ -458,7 +458,7 @@ function getAdditionalExecutableActions(
458458
}
459459
}
460460

461-
const actionInfo = getActionSchema(fullAction, context.agents);
461+
const actionInfo = tryGetActionSchema(fullAction, context.agents);
462462
if (actionInfo === undefined) {
463463
throw new Error(
464464
`Action not found ${fullAction.schemaName}.${fullAction.actionName}`,

ts/packages/dispatcher/src/execute/pendingActions.ts

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import { conversation as kp } from "knowledge-processor";
3939
import { getObjectProperty } from "common-utils";
4040
import { ActionSchemaFile } from "../translation/actionConfigProvider.js";
4141
import { ActionSchemaEntityTypeDefinition } from "../../../actionSchema/dist/type.js";
42+
import { getActionParametersType } from "../translation/actionSchemaUtils.js";
4243

4344
const debugEntities = registerDebug("typeagent:dispatcher:actions:entities");
4445

@@ -257,8 +258,8 @@ export function getEntityPropertyTypeName(
257258
return undefined;
258259
}
259260
const actionParametersType = getActionParametersType(
260-
actionName,
261261
actionSchemaFile,
262+
actionName,
262263
);
263264
const parameterType = getPropertyType(actionParametersType, paramName);
264265
if (parameterType === undefined) {
@@ -769,28 +770,6 @@ async function getParameterEntities(
769770
}
770771
}
771772

772-
export function getActionParametersType(
773-
actionName: string,
774-
actionSchemaFile: ActionSchemaFile,
775-
): ActionParamObject {
776-
const schema =
777-
actionSchemaFile.parsedActionSchema.actionSchemas.get(actionName);
778-
779-
if (schema === undefined) {
780-
throw new Error(
781-
`Action schema not found for ${actionSchemaFile.schemaName}.${actionName}`,
782-
);
783-
}
784-
785-
const actionParametersType = schema.type.fields.parameters?.type;
786-
if (actionParametersType?.type !== "object") {
787-
throw new Error(
788-
`Action schema parameter type mismatch: ${actionSchemaFile.schemaName}.${actionName}`,
789-
);
790-
}
791-
return actionParametersType;
792-
}
793-
794773
export async function resolveEntities(
795774
agents: AppAgentManager,
796775
action: TypeAgentAction<FullAction>,
@@ -804,8 +783,8 @@ export async function resolveEntities(
804783
const config = agents.getActionConfig(action.schemaName);
805784
const actionSchemaFile = agents.getActionSchemaFileForConfig(config);
806785
const actionParametersType = getActionParametersType(
807-
action.actionName,
808786
actionSchemaFile,
787+
action.actionName,
809788
);
810789

811790
let resolvedEntities: Entity[] | undefined;

0 commit comments

Comments
 (0)