mu-harness 0.16.8 → 0.16.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,8 +10,7 @@ const toSchedule = (raw) => {
10
10
  };
11
11
  export const createScheduleTaskTool = (deps) => ({
12
12
  name: 'schedule_task',
13
- description: 'Persist a recurring (cron / heartbeat) or one-shot task that runs a sub-agent under a skill on a given prompt.',
14
- prompt: 'Use `schedule_task` to register work that should run later or on a schedule: a `cron` expression, an `everyMs` heartbeat, or a one-shot `at` timestamp. It invokes a skill on a prompt, like `run_skill`.',
13
+ description: 'Persist work to run later or on a schedule: a `cron` expression, an `everyMs` heartbeat, or a one-shot `at` timestamp. It invokes a skill on a prompt (like `run_skill`) via a sub-agent.',
15
14
  parameters: {
16
15
  type: 'object',
17
16
  properties: {
@@ -72,6 +72,7 @@ export const createAgentSession = (config) => {
72
72
  };
73
73
  return {
74
74
  id,
75
+ tools,
75
76
  get messages() {
76
77
  return messages;
77
78
  },
@@ -9,6 +9,9 @@ const onFirstMessage = (session, fire) => {
9
9
  get messages() {
10
10
  return session.messages;
11
11
  },
12
+ get tools() {
13
+ return session.tools;
14
+ },
12
15
  send: async (input) => {
13
16
  if (pending) {
14
17
  pending = false;
@@ -7,6 +7,9 @@ export const persistTo = (store, session, persisted = 0) => {
7
7
  get messages() {
8
8
  return session.messages;
9
9
  },
10
+ get tools() {
11
+ return session.tools;
12
+ },
10
13
  send: async (input) => {
11
14
  await session.send(input);
12
15
  const all = session.messages;
@@ -1,4 +1,4 @@
1
- import type { ContentPart, LoopEvent, Message } from 'mu-core';
1
+ import type { ContentPart, LoopEvent, Message, Tool } from 'mu-core';
2
2
  export type AgentSessionEvent = {
3
3
  type: 'turn_start';
4
4
  input: Message;
@@ -11,6 +11,7 @@ export type AgentSessionEvent = {
11
11
  export interface AgentSession {
12
12
  readonly id: string;
13
13
  readonly messages: readonly Message[];
14
+ readonly tools: readonly Tool[];
14
15
  send(input: string | ContentPart[]): Promise<void>;
15
16
  abort(): void;
16
17
  subscribe(listener: (event: AgentSessionEvent) => void): () => void;
@@ -18,8 +18,7 @@ export const runSkill = async (deps, args) => {
18
18
  };
19
19
  export const createRunSkillTool = (deps) => ({
20
20
  name: 'run_skill',
21
- description: 'Invoke a sub-agent equipped with a named skill to carry out a specific task. Returns its final answer.',
22
- prompt: 'To carry out a self-contained task under a skill, call `run_skill` with the skill name, the task, and the agent persona to run it as.',
21
+ description: 'Invoke a sub-agent equipped with a named skill to carry out a self-contained task — pass the skill name, the task, and the agent persona to run it as. Returns its final answer.',
23
22
  parameters: {
24
23
  type: 'object',
25
24
  properties: {
@@ -1,12 +1,12 @@
1
1
  export const createSkillTool = (registry) => ({
2
2
  name: 'skill',
3
- description: "Load a named skill's instructions into the conversation, then follow them.",
4
- get prompt() {
3
+ get description() {
4
+ const base = "Load a named skill's instructions into the conversation, then follow them.";
5
5
  const list = registry.list();
6
6
  if (!list.length)
7
- return undefined;
7
+ return base;
8
8
  const catalog = list.map((skill) => `- ${skill.name}${skill.description ? `: ${skill.description}` : ''}`).join('\n');
9
- return `When a request matches one of these skills, call \`skill\` with its name BEFORE acting, then follow the returned instructions:\n${catalog}`;
9
+ return `${base} When a request matches one of these skills, call \`skill\` with its name BEFORE acting:\n${catalog}`;
10
10
  },
11
11
  parameters: {
12
12
  type: 'object',
@@ -4,8 +4,7 @@ import { parseSkill } from './parser.js';
4
4
  const slug = (name) => name.trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
5
5
  export const createSkillWriterTool = (deps) => ({
6
6
  name: 'create_skill',
7
- description: 'Create a reusable skill: a named set of instructions the agent can load on demand later.',
8
- prompt: 'When you discover a reusable workflow worth keeping, capture it with `create_skill` (name, description, instructions). Use `scope: "local"` for a skill specific to this project, or `scope: "config"` to make it available across all projects. It can then be loaded via `skill`.',
7
+ description: 'Create a reusable skill (name, description, instructions) the agent can load on demand later — capture a reusable workflow worth keeping. `scope: "local"` saves it to this project, `scope: "config"` makes it available across all projects; load it later via `skill`.',
9
8
  parameters: {
10
9
  type: 'object',
11
10
  properties: {
@@ -1,5 +1,5 @@
1
1
  import { runSubAgent } from './runner.js';
2
- const BASE_PROMPT = 'Delegate self-contained research or sub-tasks to a named sub-agent with `subagent`; treat its answer as research input.';
2
+ const BASE_PROMPT = 'Delegate an isolated, fully-specifiable task to a named sub-agent instead of doing it inline; it returns only its final answer. Pick the matching sub-agent, brief it from scratch, then verify its answer before relying on it.';
3
3
  export const createSubAgentTool = (deps) => {
4
4
  const roster = deps.registry.list()
5
5
  .filter((agent) => agent.name !== 'title')
@@ -7,8 +7,7 @@ export const createSubAgentTool = (deps) => {
7
7
  .join('\n');
8
8
  return {
9
9
  name: 'subagent',
10
- description: 'Delegate an isolated task to a named sub-agent. Returns its final answer.',
11
- prompt: roster ? `${BASE_PROMPT}\n\nAvailable sub-agents:\n${roster}` : BASE_PROMPT,
10
+ description: roster ? `${BASE_PROMPT}\n\nAvailable sub-agents:\n${roster}` : BASE_PROMPT,
12
11
  parameters: {
13
12
  type: 'object',
14
13
  properties: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mu-harness",
3
- "version": "0.16.8",
3
+ "version": "0.16.9",
4
4
  "description": "Agent harness: createHarness wires mu-core into a host — XDG paths, model registry, plugins, disk-loaded agents & skills, sub-agents, sessions (JSONL + SQLite catalog), slash commands, permission/approval hooks, an optional scheduler, and a composable TUI chat app",
5
5
  "license": "MIT",
6
6
  "main": "./script/index.js",
@@ -16,8 +16,8 @@
16
16
  "dependencies": {
17
17
  "@swc/wasm-typescript": "^1.15.0",
18
18
  "croner": "^9.0.0",
19
- "mu-core": "^0.16.8",
20
- "mu-tui": "^0.16.8"
19
+ "mu-core": "^0.16.9",
20
+ "mu-tui": "^0.16.9"
21
21
  },
22
22
  "_generatedBy": "dnt@dev"
23
23
  }
@@ -13,8 +13,7 @@ const toSchedule = (raw) => {
13
13
  };
14
14
  const createScheduleTaskTool = (deps) => ({
15
15
  name: 'schedule_task',
16
- description: 'Persist a recurring (cron / heartbeat) or one-shot task that runs a sub-agent under a skill on a given prompt.',
17
- prompt: 'Use `schedule_task` to register work that should run later or on a schedule: a `cron` expression, an `everyMs` heartbeat, or a one-shot `at` timestamp. It invokes a skill on a prompt, like `run_skill`.',
16
+ description: 'Persist work to run later or on a schedule: a `cron` expression, an `everyMs` heartbeat, or a one-shot `at` timestamp. It invokes a skill on a prompt (like `run_skill`) via a sub-agent.',
18
17
  parameters: {
19
18
  type: 'object',
20
19
  properties: {
@@ -75,6 +75,7 @@ const createAgentSession = (config) => {
75
75
  };
76
76
  return {
77
77
  id,
78
+ tools,
78
79
  get messages() {
79
80
  return messages;
80
81
  },
@@ -12,6 +12,9 @@ const onFirstMessage = (session, fire) => {
12
12
  get messages() {
13
13
  return session.messages;
14
14
  },
15
+ get tools() {
16
+ return session.tools;
17
+ },
15
18
  send: async (input) => {
16
19
  if (pending) {
17
20
  pending = false;
@@ -10,6 +10,9 @@ const persistTo = (store, session, persisted = 0) => {
10
10
  get messages() {
11
11
  return session.messages;
12
12
  },
13
+ get tools() {
14
+ return session.tools;
15
+ },
13
16
  send: async (input) => {
14
17
  await session.send(input);
15
18
  const all = session.messages;
@@ -1,4 +1,4 @@
1
- import type { ContentPart, LoopEvent, Message } from 'mu-core';
1
+ import type { ContentPart, LoopEvent, Message, Tool } from 'mu-core';
2
2
  export type AgentSessionEvent = {
3
3
  type: 'turn_start';
4
4
  input: Message;
@@ -11,6 +11,7 @@ export type AgentSessionEvent = {
11
11
  export interface AgentSession {
12
12
  readonly id: string;
13
13
  readonly messages: readonly Message[];
14
+ readonly tools: readonly Tool[];
14
15
  send(input: string | ContentPart[]): Promise<void>;
15
16
  abort(): void;
16
17
  subscribe(listener: (event: AgentSessionEvent) => void): () => void;
@@ -22,8 +22,7 @@ const runSkill = async (deps, args) => {
22
22
  exports.runSkill = runSkill;
23
23
  const createRunSkillTool = (deps) => ({
24
24
  name: 'run_skill',
25
- description: 'Invoke a sub-agent equipped with a named skill to carry out a specific task. Returns its final answer.',
26
- prompt: 'To carry out a self-contained task under a skill, call `run_skill` with the skill name, the task, and the agent persona to run it as.',
25
+ description: 'Invoke a sub-agent equipped with a named skill to carry out a self-contained task — pass the skill name, the task, and the agent persona to run it as. Returns its final answer.',
27
26
  parameters: {
28
27
  type: 'object',
29
28
  properties: {
@@ -3,13 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createSkillTool = void 0;
4
4
  const createSkillTool = (registry) => ({
5
5
  name: 'skill',
6
- description: "Load a named skill's instructions into the conversation, then follow them.",
7
- get prompt() {
6
+ get description() {
7
+ const base = "Load a named skill's instructions into the conversation, then follow them.";
8
8
  const list = registry.list();
9
9
  if (!list.length)
10
- return undefined;
10
+ return base;
11
11
  const catalog = list.map((skill) => `- ${skill.name}${skill.description ? `: ${skill.description}` : ''}`).join('\n');
12
- return `When a request matches one of these skills, call \`skill\` with its name BEFORE acting, then follow the returned instructions:\n${catalog}`;
12
+ return `${base} When a request matches one of these skills, call \`skill\` with its name BEFORE acting:\n${catalog}`;
13
13
  },
14
14
  parameters: {
15
15
  type: 'object',
@@ -7,8 +7,7 @@ const parser_js_1 = require("./parser.js");
7
7
  const slug = (name) => name.trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
8
8
  const createSkillWriterTool = (deps) => ({
9
9
  name: 'create_skill',
10
- description: 'Create a reusable skill: a named set of instructions the agent can load on demand later.',
11
- prompt: 'When you discover a reusable workflow worth keeping, capture it with `create_skill` (name, description, instructions). Use `scope: "local"` for a skill specific to this project, or `scope: "config"` to make it available across all projects. It can then be loaded via `skill`.',
10
+ description: 'Create a reusable skill (name, description, instructions) the agent can load on demand later — capture a reusable workflow worth keeping. `scope: "local"` saves it to this project, `scope: "config"` makes it available across all projects; load it later via `skill`.',
12
11
  parameters: {
13
12
  type: 'object',
14
13
  properties: {
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createSubAgentTool = void 0;
4
4
  const runner_js_1 = require("./runner.js");
5
- const BASE_PROMPT = 'Delegate self-contained research or sub-tasks to a named sub-agent with `subagent`; treat its answer as research input.';
5
+ const BASE_PROMPT = 'Delegate an isolated, fully-specifiable task to a named sub-agent instead of doing it inline; it returns only its final answer. Pick the matching sub-agent, brief it from scratch, then verify its answer before relying on it.';
6
6
  const createSubAgentTool = (deps) => {
7
7
  const roster = deps.registry.list()
8
8
  .filter((agent) => agent.name !== 'title')
@@ -10,8 +10,7 @@ const createSubAgentTool = (deps) => {
10
10
  .join('\n');
11
11
  return {
12
12
  name: 'subagent',
13
- description: 'Delegate an isolated task to a named sub-agent. Returns its final answer.',
14
- prompt: roster ? `${BASE_PROMPT}\n\nAvailable sub-agents:\n${roster}` : BASE_PROMPT,
13
+ description: roster ? `${BASE_PROMPT}\n\nAvailable sub-agents:\n${roster}` : BASE_PROMPT,
15
14
  parameters: {
16
15
  type: 'object',
17
16
  properties: {