feat(cli): add agent update command for name and labels
This commit is contained in:
@@ -16,6 +16,7 @@ import { runSendCommand } from './commands/agent/send.js'
|
||||
import { runInspectCommand } from './commands/agent/inspect.js'
|
||||
import { runWaitCommand } from './commands/agent/wait.js'
|
||||
import { runAttachCommand } from './commands/agent/attach.js'
|
||||
import { runUpdateCommand } from './commands/agent/update.js'
|
||||
import { withOutput } from './output/index.js'
|
||||
|
||||
const VERSION = '0.1.0'
|
||||
@@ -125,6 +126,21 @@ export function createCli(): Command {
|
||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||
.action(withOutput(runWaitCommand))
|
||||
|
||||
program
|
||||
.command('update')
|
||||
.description('Update an agent (alias for "paseo agent update")')
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--name <name>', "Update the agent's display name")
|
||||
.option(
|
||||
'--label <label>',
|
||||
'Add/set label(s) on the agent (can be used multiple times or comma-separated)',
|
||||
collectMultiple,
|
||||
[]
|
||||
)
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||
.action(withOutput(runUpdateCommand))
|
||||
|
||||
// Top-level local daemon shortcuts
|
||||
program.addCommand(daemonStartCommand())
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { runSendCommand } from './send.js'
|
||||
import { runInspectCommand } from './inspect.js'
|
||||
import { runWaitCommand } from './wait.js'
|
||||
import { runAttachCommand } from './attach.js'
|
||||
import { runUpdateCommand } from './update.js'
|
||||
import { withOutput } from '../../output/index.js'
|
||||
|
||||
export function createAgentCommand(): Command {
|
||||
@@ -120,5 +121,20 @@ export function createAgentCommand(): Command {
|
||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||
.action(withOutput(runArchiveCommand))
|
||||
|
||||
agent
|
||||
.command('update')
|
||||
.description("Update an agent's metadata")
|
||||
.argument('<id>', 'Agent ID (or prefix)')
|
||||
.option('--name <name>', "Update the agent's display name")
|
||||
.option(
|
||||
'--label <label>',
|
||||
'Add/set label(s) on the agent (can be used multiple times or comma-separated)',
|
||||
collectMultiple,
|
||||
[]
|
||||
)
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||
.action(withOutput(runUpdateCommand))
|
||||
|
||||
return agent
|
||||
}
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
import type { Command } from 'commander'
|
||||
import { connectToDaemon, getDaemonHost } from '../../utils/client.js'
|
||||
import type { CommandOptions, SingleResult, OutputSchema, CommandError } from '../../output/index.js'
|
||||
|
||||
/** Result type for agent update command */
|
||||
export interface AgentUpdateResult {
|
||||
agentId: string
|
||||
name: string | null
|
||||
labels: string
|
||||
}
|
||||
|
||||
/** Schema for update command output */
|
||||
export const updateSchema: OutputSchema<AgentUpdateResult> = {
|
||||
idField: 'agentId',
|
||||
columns: [
|
||||
{ header: 'AGENT ID', field: 'agentId' },
|
||||
{ header: 'NAME', field: 'name' },
|
||||
{ header: 'LABELS', field: 'labels' },
|
||||
],
|
||||
}
|
||||
|
||||
export interface AgentUpdateOptions extends CommandOptions {
|
||||
name?: string
|
||||
label?: string[]
|
||||
host?: string
|
||||
}
|
||||
|
||||
export type AgentUpdateCommandResult = SingleResult<AgentUpdateResult>
|
||||
|
||||
function parseLabelOptions(labels: string[] | undefined): Record<string, string> {
|
||||
const parsed: Record<string, string> = {}
|
||||
if (!labels) {
|
||||
return parsed
|
||||
}
|
||||
|
||||
for (const rawLabel of labels) {
|
||||
for (const segment of rawLabel.split(',')) {
|
||||
const label = segment.trim()
|
||||
if (!label) {
|
||||
continue
|
||||
}
|
||||
|
||||
const eqIndex = label.indexOf('=')
|
||||
if (eqIndex === -1) {
|
||||
const error: CommandError = {
|
||||
code: 'INVALID_LABEL',
|
||||
message: `Invalid label format: ${label}`,
|
||||
details: 'Labels must be in key=value format',
|
||||
}
|
||||
throw error
|
||||
}
|
||||
|
||||
const key = label.slice(0, eqIndex).trim()
|
||||
const value = label.slice(eqIndex + 1)
|
||||
if (!key) {
|
||||
const error: CommandError = {
|
||||
code: 'INVALID_LABEL',
|
||||
message: `Invalid label format: ${label}`,
|
||||
details: 'Labels must include a non-empty key in key=value format',
|
||||
}
|
||||
throw error
|
||||
}
|
||||
|
||||
parsed[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
return parsed
|
||||
}
|
||||
|
||||
function formatLabels(labels: Record<string, string>): string {
|
||||
const entries = Object.entries(labels)
|
||||
if (entries.length === 0) {
|
||||
return '-'
|
||||
}
|
||||
return entries.map(([key, value]) => `${key}=${value}`).join(',')
|
||||
}
|
||||
|
||||
export async function runUpdateCommand(
|
||||
agentIdArg: string,
|
||||
options: AgentUpdateOptions,
|
||||
_command: Command
|
||||
): Promise<AgentUpdateCommandResult> {
|
||||
const host = getDaemonHost({ host: options.host as string | undefined })
|
||||
|
||||
// Validate arguments
|
||||
if (!agentIdArg || agentIdArg.trim().length === 0) {
|
||||
const error: CommandError = {
|
||||
code: 'MISSING_AGENT_ID',
|
||||
message: 'Agent ID is required',
|
||||
details: 'Usage: paseo agent update <id> [--name <name>] [--label <key=value>]',
|
||||
}
|
||||
throw error
|
||||
}
|
||||
|
||||
const name = options.name?.trim()
|
||||
if (options.name !== undefined && !name) {
|
||||
const error: CommandError = {
|
||||
code: 'INVALID_NAME',
|
||||
message: 'Name cannot be empty',
|
||||
details: 'Use --name <name> with a non-empty value',
|
||||
}
|
||||
throw error
|
||||
}
|
||||
|
||||
const labels = parseLabelOptions(options.label)
|
||||
if (!name && Object.keys(labels).length === 0) {
|
||||
const error: CommandError = {
|
||||
code: 'NO_CHANGES_PROVIDED',
|
||||
message: 'Nothing to update',
|
||||
details: 'Provide at least one of: --name <name>, --label <key=value>',
|
||||
}
|
||||
throw error
|
||||
}
|
||||
|
||||
let client
|
||||
try {
|
||||
client = await connectToDaemon({ host: options.host as string | undefined })
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err)
|
||||
const error: CommandError = {
|
||||
code: 'DAEMON_NOT_RUNNING',
|
||||
message: `Cannot connect to daemon at ${host}: ${message}`,
|
||||
details: 'Start the daemon with: paseo daemon start',
|
||||
}
|
||||
throw error
|
||||
}
|
||||
|
||||
try {
|
||||
const agent = await client.fetchAgent(agentIdArg)
|
||||
if (!agent) {
|
||||
const error: CommandError = {
|
||||
code: 'AGENT_NOT_FOUND',
|
||||
message: `Agent not found: ${agentIdArg}`,
|
||||
details: 'Use "paseo ls" to list available agents',
|
||||
}
|
||||
throw error
|
||||
}
|
||||
const agentId = agent.id
|
||||
|
||||
await client.updateAgent(agentId, {
|
||||
...(name ? { name } : {}),
|
||||
...(Object.keys(labels).length > 0 ? { labels } : {}),
|
||||
})
|
||||
|
||||
const updated = await client.fetchAgent(agentId)
|
||||
if (!updated) {
|
||||
throw new Error(`Agent not found after update: ${agentId}`)
|
||||
}
|
||||
|
||||
await client.close()
|
||||
|
||||
return {
|
||||
type: 'single',
|
||||
data: {
|
||||
agentId,
|
||||
name: updated.title,
|
||||
labels: formatLabels(updated.labels),
|
||||
},
|
||||
schema: updateSchema,
|
||||
}
|
||||
} catch (err) {
|
||||
await client.close().catch(() => {})
|
||||
|
||||
// Re-throw CommandError as-is
|
||||
if (err && typeof err === 'object' && 'code' in err) {
|
||||
throw err
|
||||
}
|
||||
|
||||
const message = err instanceof Error ? err.message : String(err)
|
||||
const error: CommandError = {
|
||||
code: 'UPDATE_FAILED',
|
||||
message: `Failed to update agent: ${message}`,
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env npx tsx
|
||||
|
||||
/**
|
||||
* Phase 16: Agent Update Command Tests
|
||||
*
|
||||
* Tests the agent update command for metadata updates.
|
||||
* Since daemon may not be running, we test:
|
||||
* - Help and argument parsing
|
||||
* - Validation for required update fields
|
||||
* - Graceful daemon connection errors
|
||||
* - Top-level alias support (`paseo update`)
|
||||
*/
|
||||
|
||||
import assert from 'node:assert'
|
||||
import { $ } from 'zx'
|
||||
import { mkdtemp, rm } from 'fs/promises'
|
||||
import { tmpdir } from 'os'
|
||||
import { join } from 'path'
|
||||
|
||||
$.verbose = false
|
||||
|
||||
console.log('=== Agent Update Command Tests ===\n')
|
||||
|
||||
// Get random port that's definitely not in use (never 6767)
|
||||
const port = 10000 + Math.floor(Math.random() * 50000)
|
||||
const paseoHome = await mkdtemp(join(tmpdir(), 'paseo-test-home-'))
|
||||
|
||||
try {
|
||||
// Test 1: agent update --help shows options
|
||||
{
|
||||
console.log('Test 1: agent update --help shows options')
|
||||
const result = await $`npx paseo agent update --help`.nothrow()
|
||||
assert.strictEqual(result.exitCode, 0, 'agent update --help should exit 0')
|
||||
assert(result.stdout.includes('--name'), 'help should mention --name flag')
|
||||
assert(result.stdout.includes('--label'), 'help should mention --label flag')
|
||||
assert(result.stdout.includes('--host'), 'help should mention --host option')
|
||||
assert(result.stdout.includes('<id>'), 'help should mention required id argument')
|
||||
console.log('✓ agent update --help shows options\n')
|
||||
}
|
||||
|
||||
// Test 2: agent update requires ID argument
|
||||
{
|
||||
console.log('Test 2: agent update requires ID argument')
|
||||
const result =
|
||||
await $`PASEO_HOST=localhost:${port} PASEO_HOME=${paseoHome} npx paseo agent update --name "New Name"`.nothrow()
|
||||
assert.notStrictEqual(result.exitCode, 0, 'should fail without id')
|
||||
const output = result.stdout + result.stderr
|
||||
const hasError =
|
||||
output.toLowerCase().includes('missing') ||
|
||||
output.toLowerCase().includes('required') ||
|
||||
output.toLowerCase().includes('argument') ||
|
||||
output.toLowerCase().includes('id')
|
||||
assert(hasError, 'error should mention missing argument')
|
||||
console.log('✓ agent update requires ID argument\n')
|
||||
}
|
||||
|
||||
// Test 3: agent update requires at least one update field
|
||||
{
|
||||
console.log('Test 3: agent update requires update field')
|
||||
const result =
|
||||
await $`PASEO_HOST=localhost:${port} PASEO_HOME=${paseoHome} npx paseo agent update abc123`.nothrow()
|
||||
assert.notStrictEqual(result.exitCode, 0, 'should fail without --name/--label')
|
||||
const output = result.stdout + result.stderr
|
||||
const hasError =
|
||||
output.toLowerCase().includes('nothing to update') ||
|
||||
output.toLowerCase().includes('name') ||
|
||||
output.toLowerCase().includes('label')
|
||||
assert(hasError, 'error should mention missing update fields')
|
||||
console.log('✓ agent update requires update field\n')
|
||||
}
|
||||
|
||||
// Test 4: agent update handles daemon not running
|
||||
{
|
||||
console.log('Test 4: agent update handles daemon not running')
|
||||
const result =
|
||||
await $`PASEO_HOST=localhost:${port} PASEO_HOME=${paseoHome} npx paseo agent update abc123 --name "Renamed Agent"`.nothrow()
|
||||
assert.notStrictEqual(result.exitCode, 0, 'should fail when daemon not running')
|
||||
const output = result.stdout + result.stderr
|
||||
const hasError =
|
||||
output.toLowerCase().includes('daemon') ||
|
||||
output.toLowerCase().includes('connect') ||
|
||||
output.toLowerCase().includes('cannot')
|
||||
assert(hasError, 'error should mention connection issue')
|
||||
console.log('✓ agent update handles daemon not running\n')
|
||||
}
|
||||
|
||||
// Test 5: agent update accepts multiple/comma-separated labels
|
||||
{
|
||||
console.log('Test 5: agent update accepts multi-label syntax')
|
||||
const result =
|
||||
await $`PASEO_HOST=localhost:${port} PASEO_HOME=${paseoHome} npx paseo agent update abc123 --label ui=true,area=frontend --label priority=high`.nothrow()
|
||||
const output = result.stdout + result.stderr
|
||||
assert(!output.includes('unknown option'), 'should accept --label flag')
|
||||
assert(!output.includes('error: option'), 'should not have option parsing error')
|
||||
console.log('✓ agent update accepts multi-label syntax\n')
|
||||
}
|
||||
|
||||
// Test 6: agent --help shows update subcommand
|
||||
{
|
||||
console.log('Test 6: agent --help shows update subcommand')
|
||||
const result = await $`npx paseo agent --help`.nothrow()
|
||||
assert.strictEqual(result.exitCode, 0, 'agent --help should exit 0')
|
||||
assert(result.stdout.includes('update'), 'help should mention update subcommand')
|
||||
console.log('✓ agent --help shows update subcommand\n')
|
||||
}
|
||||
|
||||
// Test 7: top-level update alias --help works
|
||||
{
|
||||
console.log('Test 7: top-level update --help works')
|
||||
const result = await $`npx paseo update --help`.nothrow()
|
||||
assert.strictEqual(result.exitCode, 0, 'update --help should exit 0')
|
||||
assert(result.stdout.includes('--name'), 'help should mention --name flag')
|
||||
assert(result.stdout.includes('--label'), 'help should mention --label flag')
|
||||
console.log('✓ top-level update --help works\n')
|
||||
}
|
||||
|
||||
// Test 8: top-level update alias accepts flags
|
||||
{
|
||||
console.log('Test 8: top-level update alias accepts flags')
|
||||
const result =
|
||||
await $`PASEO_HOST=localhost:${port} PASEO_HOME=${paseoHome} npx paseo update abc123 --name "Alias Name" --host localhost:${port}`.nothrow()
|
||||
const output = result.stdout + result.stderr
|
||||
assert(!output.includes('unknown option'), 'should accept top-level update flags')
|
||||
assert(!output.includes('error: option'), 'should not have option parsing error')
|
||||
console.log('✓ top-level update alias accepts flags\n')
|
||||
}
|
||||
} finally {
|
||||
// Clean up temp directory
|
||||
await rm(paseoHome, { recursive: true, force: true })
|
||||
}
|
||||
|
||||
console.log('=== All agent update tests passed ===')
|
||||
@@ -1074,6 +1074,40 @@ export class DaemonClient {
|
||||
return { archivedAt: result.archivedAt };
|
||||
}
|
||||
|
||||
async updateAgent(
|
||||
agentId: string,
|
||||
updates: { name?: string; labels?: Record<string, string> }
|
||||
): Promise<void> {
|
||||
const requestId = this.createRequestId();
|
||||
const message = SessionInboundMessageSchema.parse({
|
||||
type: "update_agent_request",
|
||||
agentId,
|
||||
...(updates.name !== undefined ? { name: updates.name } : {}),
|
||||
...(updates.labels && Object.keys(updates.labels).length > 0
|
||||
? { labels: updates.labels }
|
||||
: {}),
|
||||
requestId,
|
||||
});
|
||||
const payload = await this.sendRequest({
|
||||
requestId,
|
||||
message,
|
||||
timeout: 10000,
|
||||
options: { skipQueue: true },
|
||||
select: (msg) => {
|
||||
if (msg.type !== "update_agent_response") {
|
||||
return null;
|
||||
}
|
||||
if (msg.payload.requestId !== requestId) {
|
||||
return null;
|
||||
}
|
||||
return msg.payload;
|
||||
},
|
||||
});
|
||||
if (!payload.accepted) {
|
||||
throw new Error(payload.error ?? "updateAgent rejected");
|
||||
}
|
||||
}
|
||||
|
||||
async resumeAgent(
|
||||
handle: AgentPersistenceHandle,
|
||||
overrides?: Partial<AgentSessionConfig>
|
||||
|
||||
@@ -527,6 +527,16 @@ export class AgentManager {
|
||||
this.emitState(agent);
|
||||
}
|
||||
|
||||
async setLabels(
|
||||
agentId: string,
|
||||
labels: Record<string, string>
|
||||
): Promise<void> {
|
||||
const agent = this.requireAgent(agentId);
|
||||
agent.labels = { ...agent.labels, ...labels };
|
||||
await this.persistSnapshot(agent);
|
||||
this.emitState(agent);
|
||||
}
|
||||
|
||||
notifyAgentState(agentId: string): void {
|
||||
const agent = this.agents.get(agentId);
|
||||
if (!agent || agent.internal) {
|
||||
|
||||
@@ -1125,6 +1125,15 @@ export class Session {
|
||||
await this.handleArchiveAgentRequest(msg.agentId, msg.requestId);
|
||||
break;
|
||||
|
||||
case "update_agent_request":
|
||||
await this.handleUpdateAgentRequest(
|
||||
msg.agentId,
|
||||
msg.name,
|
||||
msg.labels,
|
||||
msg.requestId
|
||||
);
|
||||
break;
|
||||
|
||||
case "set_voice_mode":
|
||||
await this.handleSetVoiceMode(msg.enabled, msg.agentId, msg.requestId);
|
||||
break;
|
||||
@@ -1506,6 +1515,88 @@ export class Session {
|
||||
});
|
||||
}
|
||||
|
||||
private async handleUpdateAgentRequest(
|
||||
agentId: string,
|
||||
name: string | undefined,
|
||||
labels: Record<string, string> | undefined,
|
||||
requestId: string
|
||||
): Promise<void> {
|
||||
this.sessionLogger.info(
|
||||
{ agentId, requestId, hasName: typeof name === "string", labelCount: labels ? Object.keys(labels).length : 0 },
|
||||
"session: update_agent_request"
|
||||
);
|
||||
|
||||
const normalizedName = name?.trim();
|
||||
const normalizedLabels =
|
||||
labels && Object.keys(labels).length > 0 ? labels : undefined;
|
||||
|
||||
if (!normalizedName && !normalizedLabels) {
|
||||
this.emit({
|
||||
type: "update_agent_response",
|
||||
payload: {
|
||||
requestId,
|
||||
agentId,
|
||||
accepted: false,
|
||||
error: "Nothing to update (provide name and/or labels)",
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const liveAgent = this.agentManager.getAgent(agentId);
|
||||
if (liveAgent) {
|
||||
if (normalizedName) {
|
||||
await this.agentManager.setTitle(agentId, normalizedName);
|
||||
}
|
||||
if (normalizedLabels) {
|
||||
await this.agentManager.setLabels(agentId, normalizedLabels);
|
||||
}
|
||||
} else {
|
||||
const existing = await this.agentStorage.get(agentId);
|
||||
if (!existing) {
|
||||
throw new Error(`Agent not found: ${agentId}`);
|
||||
}
|
||||
|
||||
await this.agentStorage.upsert({
|
||||
...existing,
|
||||
...(normalizedName ? { title: normalizedName } : {}),
|
||||
...(normalizedLabels
|
||||
? { labels: { ...existing.labels, ...normalizedLabels } }
|
||||
: {}),
|
||||
});
|
||||
}
|
||||
|
||||
this.emit({
|
||||
type: "update_agent_response",
|
||||
payload: { requestId, agentId, accepted: true, error: null },
|
||||
});
|
||||
} catch (error: any) {
|
||||
this.sessionLogger.error(
|
||||
{ err: error, agentId, requestId },
|
||||
"session: update_agent_request error"
|
||||
);
|
||||
this.emit({
|
||||
type: "activity_log",
|
||||
payload: {
|
||||
id: uuidv4(),
|
||||
timestamp: new Date(),
|
||||
type: "error",
|
||||
content: `Failed to update agent: ${error.message}`,
|
||||
},
|
||||
});
|
||||
this.emit({
|
||||
type: "update_agent_response",
|
||||
payload: {
|
||||
requestId,
|
||||
agentId,
|
||||
accepted: false,
|
||||
error: error?.message ? String(error.message) : "Failed to update agent",
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle voice mode toggle
|
||||
*/
|
||||
|
||||
@@ -422,6 +422,14 @@ export const ArchiveAgentRequestMessageSchema = z.object({
|
||||
requestId: z.string(),
|
||||
});
|
||||
|
||||
export const UpdateAgentRequestMessageSchema = z.object({
|
||||
type: z.literal("update_agent_request"),
|
||||
agentId: z.string(),
|
||||
name: z.string().optional(),
|
||||
labels: z.record(z.string()).optional(),
|
||||
requestId: z.string(),
|
||||
});
|
||||
|
||||
export const SetVoiceModeMessageSchema = z.object({
|
||||
type: z.literal("set_voice_mode"),
|
||||
enabled: z.boolean(),
|
||||
@@ -660,6 +668,16 @@ export const SetAgentThinkingResponseMessageSchema = z.object({
|
||||
}),
|
||||
});
|
||||
|
||||
export const UpdateAgentResponseMessageSchema = z.object({
|
||||
type: z.literal("update_agent_response"),
|
||||
payload: z.object({
|
||||
requestId: z.string(),
|
||||
agentId: z.string(),
|
||||
accepted: z.boolean(),
|
||||
error: z.string().nullable(),
|
||||
}),
|
||||
});
|
||||
|
||||
export const SetVoiceModeResponseMessageSchema = z.object({
|
||||
type: z.literal("set_voice_mode_response"),
|
||||
payload: z.object({
|
||||
@@ -971,6 +989,7 @@ export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
|
||||
UnsubscribeAgentUpdatesMessageSchema,
|
||||
DeleteAgentRequestMessageSchema,
|
||||
ArchiveAgentRequestMessageSchema,
|
||||
UpdateAgentRequestMessageSchema,
|
||||
SetVoiceModeMessageSchema,
|
||||
SendAgentMessageRequestSchema,
|
||||
WaitForFinishRequestSchema,
|
||||
@@ -1809,6 +1828,7 @@ export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
|
||||
SetAgentModeResponseMessageSchema,
|
||||
SetAgentModelResponseMessageSchema,
|
||||
SetAgentThinkingResponseMessageSchema,
|
||||
UpdateAgentResponseMessageSchema,
|
||||
WaitForFinishResponseMessageSchema,
|
||||
AgentPermissionRequestMessageSchema,
|
||||
AgentPermissionResolvedMessageSchema,
|
||||
@@ -1878,6 +1898,7 @@ export type SendAgentMessageResponseMessage = z.infer<
|
||||
export type SetVoiceModeResponseMessage = z.infer<
|
||||
typeof SetVoiceModeResponseMessageSchema
|
||||
>;
|
||||
export type UpdateAgentResponseMessage = z.infer<typeof UpdateAgentResponseMessageSchema>;
|
||||
export type WaitForFinishResponseMessage = z.infer<
|
||||
typeof WaitForFinishResponseMessageSchema
|
||||
>;
|
||||
@@ -1917,6 +1938,7 @@ export type SpeechModelsDownloadRequestMessage = z.infer<
|
||||
>;
|
||||
export type ResumeAgentRequestMessage = z.infer<typeof ResumeAgentRequestMessageSchema>;
|
||||
export type DeleteAgentRequestMessage = z.infer<typeof DeleteAgentRequestMessageSchema>;
|
||||
export type UpdateAgentRequestMessage = z.infer<typeof UpdateAgentRequestMessageSchema>;
|
||||
export type InitializeAgentRequestMessage = z.infer<typeof InitializeAgentRequestMessageSchema>;
|
||||
export type SetAgentModeRequestMessage = z.infer<typeof SetAgentModeRequestMessageSchema>;
|
||||
export type SetAgentModelRequestMessage = z.infer<typeof SetAgentModelRequestMessageSchema>;
|
||||
|
||||
Reference in New Issue
Block a user