Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tightened up help output & added action commands for some system commands #514

Merged
merged 8 commits into from
Dec 23, 2024
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
3 changes: 3 additions & 0 deletions .github/workflows/build-ts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ permissions:
pull-requests: read
contents: read

env:
NODE_OPTIONS: --max_old_space_size=8192

jobs:
build_ts:
strategy:
Expand Down
93 changes: 93 additions & 0 deletions ts/packages/dispatcher/src/command/commandHelp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

import {
ActionContext,
CommandDescriptor,
CommandDescriptorTable,
} from "@typeagent/agent-sdk";
Expand All @@ -12,6 +13,9 @@ import {
isCommandDescriptorTable,
} from "@typeagent/agent-sdk/helpers/command";
import { getDefaultSubCommandDescriptor } from "./command.js";
import { displayResult } from "@typeagent/agent-sdk/helpers/display";
import { dispatcherAgent } from "../context/dispatcher/dispatcherAgent.js";
import { success } from "typechat";

export function getUsage(command: string, descriptor: CommandDescriptor) {
if (descriptor.help) {
Expand Down Expand Up @@ -117,3 +121,92 @@ export function getHandlerTableUsage(
}
return output.join("\n");
}

export function printStructuredHandlerTableUsage(
table: CommandDescriptorTable,
command: string | undefined,
context: ActionContext<CommandHandlerContext>,
) {
let index: number = 0;
const commands: string[][] = [];

if (command) {
const defaultSubCommand = getDefaultSubCommandDescriptor(table);
if (defaultSubCommand !== undefined) {
displayResult(`${chalk.bold(chalk.underline("Command"))}`, context);
displayResult(getUsage(command, defaultSubCommand), context);
displayResult("\n", context);
}

if (Object.keys(table.commands).length == 0) {
return;
}

displayResult(
`${chalk.bold(chalk.underline(`Subcommands: ${table.description}`))}`,
context,
);
displayResult("\n", context);
displayResult(
`${chalk.bold("Usage")}: @${command} <subcommand> ...`,
context,
);
displayResult("\n", context);
} else {
displayResult(
`${chalk.bold(chalk.underline(table.description))}`,
context,
);
displayResult("\n", context);
displayResult(
`${chalk.bold("Usage")}: @[<agentName>] <subcommand> ...`,
context,
);
displayResult("\n", context);

commands[index] = ["Agent Name (* default agent)", "Description"];
index++;

const systemContext = context.sessionContext.agentContext;
for (const name of systemContext.agents.getAppAgentNames()) {
if (systemContext.agents.isCommandEnabled(name)) {
commands[index] = [];

if (name == "system") {
commands[index].push(`${name} *`);
} else {
commands[index].push(name);
}

commands[index].push(
systemContext.agents.getAppAgentDescription(name),
);

index++;
}
}

displayResult(commands, context);
displayResult("\n", context);
}

const subCommands: string[][] = [];
index = 0;

subCommands[index] = ["Sub commands", "Description"];
index++;

for (const name in table.commands) {
const handler = table.commands[name];
const subcommand = isCommandDescriptorTable(handler)
? `${name} <subcommand>`
: name;

subCommands[index] = [];
subCommands[index].push(subcommand);
subCommands[index].push(handler.description);
index++;
}

displayResult(subCommands, context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ function clarifyRequestAction(

export const dispatcherManifest: AppAgentManifest = {
emojiChar: "🤖",
description: "Built-in agent to dispatch request",
description: "Built-in agent to dispatch requests",
schema: {
description: "",
schemaType: "DispatcherActions",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { processCommandNoLock } from "../../../command/command.js";
import { CommandHandlerContext } from "../../commandHandlerContext.js";
import { ConfigAction } from "../schema/configActionSchema.js";
import { ConfigAction, ToggleAgent } from "../schema/configActionSchema.js";
import { AppAction, ActionContext } from "@typeagent/agent-sdk";

export async function executeConfigAction(
Expand All @@ -12,9 +12,20 @@ export async function executeConfigAction(
) {
const configAction = action as unknown as ConfigAction;
switch (configAction.actionName) {
case "toggleBot":
case "listAgents":
await processCommandNoLock(
`@config bot ${configAction.parameters.enable ? "on" : "off"}`,
`@config agent`,
context.sessionContext.agentContext,
);
break;
case "toggleAgent":
const agentAction = configAction as ToggleAgent;
const cmdParam: string = configAction.parameters.enable
? ``
: `--off`;

await processCommandNoLock(
`@config agent ${cmdParam} ${configAction.parameters.agentNames.join(" ")}`,
context.sessionContext.agentContext,
);
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { ActionContext, AppAction } from "@typeagent/agent-sdk";
import { CommandHandlerContext } from "../../commandHandlerContext.js";
import { processCommandNoLock } from "../../../command/command.js";
import {
DeleteHistoryAction,
HistoryAction,
} from "../schema/historyActionSchema.js";

export async function executeHistoryAction(
action: AppAction,
context: ActionContext<CommandHandlerContext>,
) {
const historyAction = action as HistoryAction;
switch (historyAction.actionName) {
case "delete":
const deleteAction = historyAction as DeleteHistoryAction;
await processCommandNoLock(
`@history delete ${deleteAction.parameters.messageNumber}`,
context.sessionContext.agentContext,
);
break;
case "clear":
await processCommandNoLock(
`@history clear`,
context.sessionContext.agentContext,
);
break;
case "list":
await processCommandNoLock(
`@history list`,
context.sessionContext.agentContext,
);
break;
default:
throw new Error(`Invalid action name: ${action.actionName}`);
}
return undefined;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { ActionContext, AppAction } from "@typeagent/agent-sdk";
import {
NotificationAction,
ShowNotificationsAction,
} from "../schema/notificationActionSchema.js";
import { CommandHandlerContext } from "../../commandHandlerContext.js";
import { processCommandNoLock } from "../../../command/command.js";

export async function executeNotificationAction(
action: AppAction,
context: ActionContext<CommandHandlerContext>,
) {
const notificationAction = action as NotificationAction;
switch (notificationAction.actionName) {
case "show":
const showAction = notificationAction as ShowNotificationsAction;
await processCommandNoLock(
`@notify show ${showAction.parameters.filter}`,
context.sessionContext.agentContext,
);
break;
case "summary":
await processCommandNoLock(
`@notify info`,
context.sessionContext.agentContext,
);
break;
case "clear":
await processCommandNoLock(
`@notify clear`,
context.sessionContext.agentContext,
);
break;
default:
throw new Error(`Invalid action name: ${action.actionName}`);
}
return undefined;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,22 @@
// Licensed under the MIT License.

export type ConfigAction =
| ToggleBotAction
| ListAgents
| ToggleAgent
| ToggleExplanationAction
| ToggleDeveloperModeAction;

// Toggle use of LLM, bot or AI.
export type ToggleBotAction = {
actionName: "toggleBot";
// Shows the list of available agents
export type ListAgents = {
actionName: "listAgents";
};

// Toggle use of LLM, agent or AI.
export type ToggleAgent = {
actionName: "toggleAgent";
parameters: {
enable: boolean;
agentNames: string[];
};
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

export type HistoryAction =
| ListHistoryAction
| ClearHistoryAction
| DeleteHistoryAction;

// Shows the chat history
export type ListHistoryAction = {
actionName: "list";
};

// Clears the chat history
export type ClearHistoryAction = {
actionName: "clear";
};

// Deletes a specific message from the chat history
export type DeleteHistoryAction = {
actionName: "delete";
parameters: {
messageNumber: number;
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

export type NotificationAction =
| ShowNotificationsAction
| ShowNotificationSummaryAction
| ClearNotificationsAction;

// Shows notifications based on the supplied filter
export type ShowNotificationsAction = {
actionName: "show";
parameters: {
filter: NotificationFilter;
};
};

export type NotificationFilter = "all" | "unread";

// Shows notification summary
export type ShowNotificationSummaryAction = {
actionName: "summary";
};

// Clears the notifications
export type ClearNotificationsAction = {
actionName: "clear";
};
Loading
Loading