Files
dsh-easy-desktop/plugins/agentrq/src/tools.ts
TommyFang 73cb4cec60 feat: integrate AgentRQ task manager plugin
- Clone agentrq/agentrq plugin to plugins/agentrq/
- Update package.json name to 'agentrq'
- Add agentrq plugin to tauri.conf.json resources
- Add AGENTRQ_PACKAGE constant and bundled_agentrq_plugin() discovery
- Add install_agentrq_plugin() function to modlens.rs
- Update README with plugin listing
2026-08-16 12:13:11 +08:00

101 lines
4.3 KiB
TypeScript

/**
* The `agentrq_autopull` management tool.
*
* Task CRUD already reaches the model as `mcp__agentrq__*` through the harness
* MCP bridge; this tool covers only what that bridge cannot express — the
* plugin's own polling state, and an on-demand dequeue that returns the task as
* a tool result instead of waiting for the next tick.
*
* @module @agentrq/dsh-plugin-agentrq
*/
import type { Context } from '@deepseek-ai/cordis'
import { defineTool } from '@deepseek-ai/dsh-tools'
import type { AgentRqRuntime } from './runtime.js'
/** Actions the model may take on the auto-pull runtime. */
const ACTIONS = ['status', 'pause', 'resume', 'pull_now'] as const
/**
* Register the tool in one agent's scope.
*
* @param agentCtx - the agent-scoped context that owns the registration.
* @param runtime - that agent's auto-pull runtime.
* @returns a disposer that unregisters the tool.
*/
export function registerAutoPullTool(agentCtx: Context, runtime: AgentRqRuntime): () => void {
return agentCtx.tools.register(defineTool({
name: 'agentrq_autopull',
description: [
'Inspect or steer automatic delivery of AgentRQ work into this session.',
'The workspace pushes tasks and messages on its own; this tool does not fetch them on a timer.',
'"status" reports the workspace connection and whether delivery is on;',
'"pause" and "resume" stop and restart delivery into this session;',
'"pull_now" dequeues the next task assigned to you right away and returns it.',
'Task content, replies, and status changes go through the mcp__agentrq__* tools, not this one.',
].join(' '),
parameters: {
action: {
type: 'string',
enum: ACTIONS,
required: true,
description: 'status | pause | resume | pull_now',
},
},
output: {
schema: {
type: 'object',
additionalProperties: false,
properties: {
active: { type: 'boolean', required: true, description: 'Whether workspace pushes are reaching this session.' },
configured: { type: 'boolean', required: true, description: 'Whether delivery is enabled in configuration.' },
connected: { type: 'boolean', required: true, description: 'Whether the workspace session is established.' },
lastDeliveredTaskId: {
oneOf: [{ type: 'string' }, { type: 'null' }],
required: true,
description: 'Task id most recently handed to this session, or null.',
},
task: {
oneOf: [
{
type: 'object',
additionalProperties: false,
properties: {
id: { type: 'string', required: true, description: 'Base62 task id.' },
title: { type: 'string', required: true, description: 'Task title.' },
status: { type: 'string', required: true, description: 'Task status at fetch time.' },
text: { type: 'string', required: true, description: 'The workspace rendering of the task.' },
},
},
{ type: 'null' },
],
required: true,
description: 'The dequeued task for "pull_now", or null when the queue was empty or the action was not a pull.',
},
},
},
render: (args, value) => {
if (args.action !== 'pull_now') {
const state = value.active ? 'on' : value.configured ? 'paused' : 'disabled'
const link = value.connected ? 'connected' : 'reconnecting'
return [{ type: 'text', text: `AgentRQ delivery is ${state}; workspace session ${link}.` }]
}
if (value.task === null) return [{ type: 'text', text: 'AgentRQ queue is empty; no task assigned to you.' }]
return [{ type: 'text', text: value.task.text }]
},
},
async execute(args, exec) {
if (args.action === 'pull_now') {
const task = await runtime.pullNow(exec.signal)
return { ...runtime.status(), task: task === undefined ? null : { id: task.id, title: task.title, status: task.status, text: task.text } }
}
const status = args.action === 'pause'
? runtime.pause()
: args.action === 'resume'
? runtime.resume()
: runtime.status()
return { ...status, task: null }
},
}))
}