@rubytech/taskmaster 1.42.0 → 1.42.1
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.
- package/dist/agents/context.js +2 -0
- package/dist/agents/pi-embedded-runner/compact.js +1 -0
- package/dist/agents/pi-embedded-runner/run/attempt.js +1 -0
- package/dist/agents/pi-embedded-runner/system-prompt.js +1 -0
- package/dist/agents/skills/frontmatter.js +85 -1
- package/dist/agents/skills/workspace.js +23 -2
- package/dist/agents/skills-status.js +2 -2
- package/dist/agents/system-prompt.js +43 -30
- package/dist/agents/tool-policy.js +68 -4
- package/dist/agents/tools/access-manage-tool.js +110 -0
- package/dist/agents/tools/account-manage-tool.js +78 -0
- package/dist/agents/tools/brand-settings-tool.js +53 -24
- package/dist/agents/tools/file-manage-tool.js +193 -0
- package/dist/agents/tools/license-manage-tool.js +50 -0
- package/dist/agents/tools/skill-manage-tool.js +16 -3
- package/dist/auto-reply/reply/commands-context-report.js +2 -1
- package/dist/browser/chrome.js +11 -0
- package/dist/build-info.json +3 -3
- package/dist/cli/skills-cli.js +4 -9
- package/dist/commands/onboard-skills.js +1 -1
- package/dist/config/zod-schema.js +5 -1
- package/dist/control-ui/assets/index-CAu2PL0O.css +1 -0
- package/dist/control-ui/assets/{index-Cl91wvkO.js → index-c6Rca5oP.js} +691 -542
- package/dist/control-ui/assets/index-c6Rca5oP.js.map +1 -0
- package/dist/control-ui/index.html +3 -2
- package/dist/gateway/protocol/index.js +3 -2
- package/dist/gateway/protocol/schema/agents-models-skills.js +6 -1
- package/dist/gateway/protocol/schema/tools.js +8 -0
- package/dist/gateway/server-methods/sessions.js +3 -1
- package/dist/gateway/server-methods/skills.js +31 -2
- package/dist/gateway/server-methods/tools.js +7 -0
- package/dist/gateway/server-methods.js +3 -0
- package/dist/gateway/session-utils.js +5 -1
- package/dist/media-understanding/apply.js +18 -4
- package/dist/web/auto-reply/monitor/process-message.js +1 -0
- package/dist/web/inbound/monitor.js +4 -0
- package/package.json +1 -1
- package/skills/skill-builder/SKILL.md +18 -4
- package/skills/skill-builder/references/lean-pattern.md +13 -3
- package/dist/control-ui/assets/index-Cl91wvkO.js.map +0 -1
- package/dist/control-ui/assets/index-Dd2cHcuh.css +0 -1
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
<title>Taskmaster Control</title>
|
|
7
7
|
<meta name="color-scheme" content="dark light" />
|
|
8
8
|
<link rel="icon" type="image/png" href="./favicon.png?v=2" />
|
|
9
|
-
<script type="module" crossorigin src="./assets/index-
|
|
10
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
9
|
+
<script type="module" crossorigin src="./assets/index-c6Rca5oP.js"></script>
|
|
10
|
+
<link rel="stylesheet" crossorigin href="./assets/index-CAu2PL0O.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
13
13
|
<taskmaster-app></taskmaster-app>
|
|
14
|
+
<script src="https://unpkg.com/lucide@latest" defer></script>
|
|
14
15
|
</body>
|
|
15
16
|
</html>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import AjvPkg from "ajv";
|
|
2
|
-
import { AgentEventSchema, AgentIdentityParamsSchema, AgentIdentityResultSchema, AgentParamsSchema, AgentSummarySchema, AgentsListParamsSchema, AgentsListResultSchema, AgentWaitParamsSchema, ChannelsLogoutParamsSchema, ChannelsProbeTokenParamsSchema, ChannelsStatusParamsSchema, ChannelsStatusResultSchema, ChatAbortParamsSchema, ChatEventSchema, ChatHistoryParamsSchema, ChatInjectParamsSchema, ChatSendParamsSchema, ConfigApplyParamsSchema, ConfigGetParamsSchema, ConfigPatchParamsSchema, ConfigSchemaParamsSchema, ConfigSchemaResponseSchema, ConfigSetParamsSchema, ConnectParamsSchema, CronAddParamsSchema, CronJobSchema, CronListParamsSchema, CronRemoveParamsSchema, CronRunParamsSchema, CronRunsParamsSchema, CronStatusParamsSchema, CronUpdateParamsSchema, DevicePairApproveParamsSchema, DevicePairListParamsSchema, DevicePairRejectParamsSchema, DeviceTokenRevokeParamsSchema, DeviceTokenRotateParamsSchema, ExecApprovalsGetParamsSchema, ExecApprovalsNodeGetParamsSchema, ExecApprovalsNodeSetParamsSchema, ExecApprovalsSetParamsSchema, ExecApprovalRequestParamsSchema, ExecApprovalResolveParamsSchema, ErrorCodes, ErrorShapeSchema, EventFrameSchema, errorShape, GatewayFrameSchema, HelloOkSchema, LogsTailParamsSchema, LogsTailResultSchema, SessionsTranscriptParamsSchema, SessionsTranscriptResultSchema, ModelsListParamsSchema, NodeDescribeParamsSchema, NodeEventParamsSchema, NodeInvokeParamsSchema, NodeInvokeResultParamsSchema, NodeListParamsSchema, NodePairApproveParamsSchema, NodePairListParamsSchema, NodePairRejectParamsSchema, NodePairRequestParamsSchema, NodePairVerifyParamsSchema, NodeRenameParamsSchema, PollParamsSchema, PROTOCOL_VERSION, PresenceEntrySchema, ProtocolSchemas, RequestFrameSchema, ResponseFrameSchema, SendParamsSchema, SessionsCompactParamsSchema, SessionsDeleteParamsSchema, SessionsListParamsSchema, SessionsPatchParamsSchema, SessionsPreviewParamsSchema, SessionsResetParamsSchema, SessionsResolveParamsSchema, ShutdownEventSchema, SkillsBinsParamsSchema, SkillsCreateParamsSchema, SkillsDeleteParamsSchema, SkillsDeleteDraftParamsSchema, SkillsDraftsParamsSchema, SkillsSaveDraftParamsSchema, SkillsInstallParamsSchema, SkillsReadParamsSchema, SkillsStatusParamsSchema, SkillsUpdateParamsSchema, SnapshotSchema, StateVersionSchema, TalkModeParamsSchema, TickEventSchema, UpdateRunParamsSchema, WakeParamsSchema, WebLoginStartParamsSchema, WebLoginWaitParamsSchema, WizardCancelParamsSchema, WizardNextParamsSchema, WizardNextResultSchema, WhatsAppConversationsParamsSchema, WhatsAppGroupInfoParamsSchema, WhatsAppMessagesParamsSchema, WhatsAppSendMessageParamsSchema, WhatsAppSetActivationParamsSchema, WizardStartParamsSchema, WizardStartResultSchema, WizardStatusParamsSchema, WizardStatusResultSchema, WizardStepSchema, } from "./schema.js";
|
|
2
|
+
import { AgentEventSchema, AgentIdentityParamsSchema, AgentIdentityResultSchema, AgentParamsSchema, AgentSummarySchema, AgentsListParamsSchema, AgentsListResultSchema, AgentWaitParamsSchema, ChannelsLogoutParamsSchema, ChannelsProbeTokenParamsSchema, ChannelsStatusParamsSchema, ChannelsStatusResultSchema, ChatAbortParamsSchema, ChatEventSchema, ChatHistoryParamsSchema, ChatInjectParamsSchema, ChatSendParamsSchema, ConfigApplyParamsSchema, ConfigGetParamsSchema, ConfigPatchParamsSchema, ConfigSchemaParamsSchema, ConfigSchemaResponseSchema, ConfigSetParamsSchema, ConnectParamsSchema, CronAddParamsSchema, CronJobSchema, CronListParamsSchema, CronRemoveParamsSchema, CronRunParamsSchema, CronRunsParamsSchema, CronStatusParamsSchema, CronUpdateParamsSchema, DevicePairApproveParamsSchema, DevicePairListParamsSchema, DevicePairRejectParamsSchema, DeviceTokenRevokeParamsSchema, DeviceTokenRotateParamsSchema, ExecApprovalsGetParamsSchema, ExecApprovalsNodeGetParamsSchema, ExecApprovalsNodeSetParamsSchema, ExecApprovalsSetParamsSchema, ExecApprovalRequestParamsSchema, ExecApprovalResolveParamsSchema, ErrorCodes, ErrorShapeSchema, EventFrameSchema, errorShape, GatewayFrameSchema, HelloOkSchema, LogsTailParamsSchema, LogsTailResultSchema, SessionsTranscriptParamsSchema, SessionsTranscriptResultSchema, ModelsListParamsSchema, NodeDescribeParamsSchema, NodeEventParamsSchema, NodeInvokeParamsSchema, NodeInvokeResultParamsSchema, NodeListParamsSchema, NodePairApproveParamsSchema, NodePairListParamsSchema, NodePairRejectParamsSchema, NodePairRequestParamsSchema, NodePairVerifyParamsSchema, NodeRenameParamsSchema, PollParamsSchema, PROTOCOL_VERSION, PresenceEntrySchema, ProtocolSchemas, RequestFrameSchema, ResponseFrameSchema, SendParamsSchema, SessionsCompactParamsSchema, SessionsDeleteParamsSchema, SessionsListParamsSchema, SessionsPatchParamsSchema, SessionsPreviewParamsSchema, SessionsResetParamsSchema, SessionsResolveParamsSchema, ShutdownEventSchema, SkillsBinsParamsSchema, SkillsCreateParamsSchema, SkillsDeleteParamsSchema, SkillsDeleteDraftParamsSchema, SkillsDraftsParamsSchema, SkillsSaveDraftParamsSchema, SkillsInstallParamsSchema, SkillsPatchParamsSchema, SkillsReadParamsSchema, SkillsStatusParamsSchema, SkillsUpdateParamsSchema, SnapshotSchema, StateVersionSchema, TalkModeParamsSchema, TickEventSchema, UpdateRunParamsSchema, WakeParamsSchema, WebLoginStartParamsSchema, WebLoginWaitParamsSchema, WizardCancelParamsSchema, WizardNextParamsSchema, WizardNextResultSchema, WhatsAppConversationsParamsSchema, WhatsAppGroupInfoParamsSchema, WhatsAppMessagesParamsSchema, WhatsAppSendMessageParamsSchema, WhatsAppSetActivationParamsSchema, WizardStartParamsSchema, WizardStartResultSchema, WizardStatusParamsSchema, WizardStatusResultSchema, WizardStepSchema, } from "./schema.js";
|
|
3
3
|
const ajv = new AjvPkg({
|
|
4
4
|
allErrors: true,
|
|
5
5
|
strict: false,
|
|
@@ -52,6 +52,7 @@ export const validateSkillsStatusParams = ajv.compile(SkillsStatusParamsSchema);
|
|
|
52
52
|
export const validateSkillsBinsParams = ajv.compile(SkillsBinsParamsSchema);
|
|
53
53
|
export const validateSkillsInstallParams = ajv.compile(SkillsInstallParamsSchema);
|
|
54
54
|
export const validateSkillsUpdateParams = ajv.compile(SkillsUpdateParamsSchema);
|
|
55
|
+
export const validateSkillsPatchParams = ajv.compile(SkillsPatchParamsSchema);
|
|
55
56
|
export const validateSkillsReadParams = ajv.compile(SkillsReadParamsSchema);
|
|
56
57
|
export const validateSkillsCreateParams = ajv.compile(SkillsCreateParamsSchema);
|
|
57
58
|
export const validateSkillsDeleteParams = ajv.compile(SkillsDeleteParamsSchema);
|
|
@@ -119,4 +120,4 @@ export function formatValidationErrors(errors) {
|
|
|
119
120
|
}
|
|
120
121
|
return unique.join("; ");
|
|
121
122
|
}
|
|
122
|
-
export { ConnectParamsSchema, HelloOkSchema, RequestFrameSchema, ResponseFrameSchema, EventFrameSchema, GatewayFrameSchema, PresenceEntrySchema, SnapshotSchema, ErrorShapeSchema, StateVersionSchema, AgentEventSchema, ChatEventSchema, SendParamsSchema, PollParamsSchema, AgentParamsSchema, AgentIdentityParamsSchema, AgentIdentityResultSchema, WakeParamsSchema, NodePairRequestParamsSchema, NodePairListParamsSchema, NodePairApproveParamsSchema, NodePairRejectParamsSchema, NodePairVerifyParamsSchema, NodeListParamsSchema, NodeInvokeParamsSchema, SessionsListParamsSchema, SessionsPreviewParamsSchema, SessionsPatchParamsSchema, SessionsResetParamsSchema, SessionsDeleteParamsSchema, SessionsCompactParamsSchema, ConfigGetParamsSchema, ConfigSetParamsSchema, ConfigApplyParamsSchema, ConfigPatchParamsSchema, ConfigSchemaParamsSchema, ConfigSchemaResponseSchema, WizardStartParamsSchema, WizardNextParamsSchema, WizardCancelParamsSchema, WizardStatusParamsSchema, WizardStepSchema, WizardNextResultSchema, WizardStartResultSchema, WizardStatusResultSchema, ChannelsStatusParamsSchema, ChannelsStatusResultSchema, ChannelsLogoutParamsSchema, ChannelsProbeTokenParamsSchema, WebLoginStartParamsSchema, WebLoginWaitParamsSchema, WhatsAppConversationsParamsSchema, WhatsAppGroupInfoParamsSchema, WhatsAppMessagesParamsSchema, WhatsAppSendMessageParamsSchema, WhatsAppSetActivationParamsSchema, AgentSummarySchema, AgentsListParamsSchema, AgentsListResultSchema, ModelsListParamsSchema, SkillsStatusParamsSchema, SkillsInstallParamsSchema, SkillsUpdateParamsSchema, CronJobSchema, CronListParamsSchema, CronStatusParamsSchema, CronAddParamsSchema, CronUpdateParamsSchema, CronRemoveParamsSchema, CronRunParamsSchema, CronRunsParamsSchema, LogsTailParamsSchema, LogsTailResultSchema, SessionsTranscriptParamsSchema, SessionsTranscriptResultSchema, ChatHistoryParamsSchema, ChatSendParamsSchema, ChatInjectParamsSchema, UpdateRunParamsSchema, TickEventSchema, ShutdownEventSchema, ProtocolSchemas, PROTOCOL_VERSION, ErrorCodes, errorShape, };
|
|
123
|
+
export { ConnectParamsSchema, HelloOkSchema, RequestFrameSchema, ResponseFrameSchema, EventFrameSchema, GatewayFrameSchema, PresenceEntrySchema, SnapshotSchema, ErrorShapeSchema, StateVersionSchema, AgentEventSchema, ChatEventSchema, SendParamsSchema, PollParamsSchema, AgentParamsSchema, AgentIdentityParamsSchema, AgentIdentityResultSchema, WakeParamsSchema, NodePairRequestParamsSchema, NodePairListParamsSchema, NodePairApproveParamsSchema, NodePairRejectParamsSchema, NodePairVerifyParamsSchema, NodeListParamsSchema, NodeInvokeParamsSchema, SessionsListParamsSchema, SessionsPreviewParamsSchema, SessionsPatchParamsSchema, SessionsResetParamsSchema, SessionsDeleteParamsSchema, SessionsCompactParamsSchema, ConfigGetParamsSchema, ConfigSetParamsSchema, ConfigApplyParamsSchema, ConfigPatchParamsSchema, ConfigSchemaParamsSchema, ConfigSchemaResponseSchema, WizardStartParamsSchema, WizardNextParamsSchema, WizardCancelParamsSchema, WizardStatusParamsSchema, WizardStepSchema, WizardNextResultSchema, WizardStartResultSchema, WizardStatusResultSchema, ChannelsStatusParamsSchema, ChannelsStatusResultSchema, ChannelsLogoutParamsSchema, ChannelsProbeTokenParamsSchema, WebLoginStartParamsSchema, WebLoginWaitParamsSchema, WhatsAppConversationsParamsSchema, WhatsAppGroupInfoParamsSchema, WhatsAppMessagesParamsSchema, WhatsAppSendMessageParamsSchema, WhatsAppSetActivationParamsSchema, AgentSummarySchema, AgentsListParamsSchema, AgentsListResultSchema, ModelsListParamsSchema, SkillsStatusParamsSchema, SkillsInstallParamsSchema, SkillsPatchParamsSchema, SkillsUpdateParamsSchema, CronJobSchema, CronListParamsSchema, CronStatusParamsSchema, CronAddParamsSchema, CronUpdateParamsSchema, CronRemoveParamsSchema, CronRunParamsSchema, CronRunsParamsSchema, LogsTailParamsSchema, LogsTailResultSchema, SessionsTranscriptParamsSchema, SessionsTranscriptResultSchema, ChatHistoryParamsSchema, ChatSendParamsSchema, ChatInjectParamsSchema, UpdateRunParamsSchema, TickEventSchema, ShutdownEventSchema, ProtocolSchemas, PROTOCOL_VERSION, ErrorCodes, errorShape, };
|
|
@@ -44,10 +44,15 @@ export const SkillsUpdateParamsSchema = Type.Object({
|
|
|
44
44
|
enabled: Type.Optional(Type.Boolean()),
|
|
45
45
|
apiKey: Type.Optional(Type.String()),
|
|
46
46
|
env: Type.Optional(Type.Record(NonEmptyString, Type.String())),
|
|
47
|
-
agents: Type.Optional(Type.Array(Type.Union([Type.Literal("admin"), Type.Literal("public")]), {
|
|
47
|
+
agents: Type.Optional(Type.Array(Type.Union([Type.Literal("admin"), Type.Literal("public"), Type.Literal("subagent")]), {
|
|
48
48
|
minItems: 1,
|
|
49
49
|
})),
|
|
50
50
|
}, { additionalProperties: false });
|
|
51
|
+
export const SkillsPatchParamsSchema = Type.Object({
|
|
52
|
+
name: Type.String({ minLength: 1 }),
|
|
53
|
+
icon: Type.Optional(Type.String()),
|
|
54
|
+
tools: Type.Optional(Type.Array(Type.String())),
|
|
55
|
+
});
|
|
51
56
|
export const SkillsReadParamsSchema = Type.Object({
|
|
52
57
|
name: NonEmptyString,
|
|
53
58
|
}, { additionalProperties: false });
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import { abortEmbeddedPiRun, waitForEmbeddedPiRunEnd } from "../../agents/pi-embedded.js";
|
|
4
|
+
import { modelCacheReady } from "../../agents/context.js";
|
|
4
5
|
import { stopSubagentsForRequester } from "../../auto-reply/reply/abort.js";
|
|
5
6
|
import { clearSessionQueues } from "../../auto-reply/reply/queue.js";
|
|
6
7
|
import { loadConfig } from "../../config/config.js";
|
|
@@ -10,7 +11,8 @@ import { archiveFileOnDisk, listSessionsFromStore, loadCombinedSessionStoreForGa
|
|
|
10
11
|
import { applySessionsPatchToStore } from "../sessions-patch.js";
|
|
11
12
|
import { resolveSessionKeyFromResolveParams } from "../sessions-resolve.js";
|
|
12
13
|
export const sessionsHandlers = {
|
|
13
|
-
"sessions.list": ({ params, respond }) => {
|
|
14
|
+
"sessions.list": async ({ params, respond }) => {
|
|
15
|
+
await modelCacheReady;
|
|
14
16
|
if (!validateSessionsListParams(params)) {
|
|
15
17
|
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `invalid sessions.list params: ${formatValidationErrors(validateSessionsListParams.errors)}`));
|
|
16
18
|
return;
|
|
@@ -4,11 +4,11 @@ import { resolveAgentWorkspaceDir, resolveAgentWorkspaceRoot, resolveDefaultAgen
|
|
|
4
4
|
import { installSkill } from "../../agents/skills-install.js";
|
|
5
5
|
import { buildWorkspaceSkillStatus } from "../../agents/skills-status.js";
|
|
6
6
|
import { loadWorkspaceSkillEntries, resolveBundledSkillsDir, } from "../../agents/skills.js";
|
|
7
|
-
import { extractEmbedFlag, applyEmbedFlag } from "../../agents/skills/frontmatter.js";
|
|
7
|
+
import { extractEmbedFlag, applyEmbedFlag, applySkillMetadataFields, } from "../../agents/skills/frontmatter.js";
|
|
8
8
|
import { bumpSkillsSnapshotVersion } from "../../agents/skills/refresh.js";
|
|
9
9
|
import { loadConfig, writeConfigFile } from "../../config/config.js";
|
|
10
10
|
import { getRemoteSkillEligibility } from "../../infra/skills-remote.js";
|
|
11
|
-
import { ErrorCodes, errorShape, formatValidationErrors, validateSkillsBinsParams, validateSkillsCreateParams, validateSkillsDeleteDraftParams, validateSkillsDeleteParams, validateSkillsDraftsParams, validateSkillsInstallParams, validateSkillsReadParams, validateSkillsSaveDraftParams, validateSkillsStatusParams, validateSkillsUpdateParams, } from "../protocol/index.js";
|
|
11
|
+
import { ErrorCodes, errorShape, formatValidationErrors, validateSkillsBinsParams, validateSkillsCreateParams, validateSkillsDeleteDraftParams, validateSkillsDeleteParams, validateSkillsDraftsParams, validateSkillsInstallParams, validateSkillsReadParams, validateSkillsSaveDraftParams, validateSkillsPatchParams, validateSkillsStatusParams, validateSkillsUpdateParams, } from "../protocol/index.js";
|
|
12
12
|
function listWorkspaceDirs(cfg) {
|
|
13
13
|
const dirs = new Set();
|
|
14
14
|
const list = cfg.agents?.list;
|
|
@@ -163,6 +163,35 @@ export const skillsHandlers = {
|
|
|
163
163
|
await writeConfigFile(nextConfig);
|
|
164
164
|
respond(true, { ok: true, skillKey: p.skillKey, config: current }, undefined);
|
|
165
165
|
},
|
|
166
|
+
"skills.patch": ({ params, respond }) => {
|
|
167
|
+
if (!validateSkillsPatchParams(params)) {
|
|
168
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `invalid skills.patch params: ${formatValidationErrors(validateSkillsPatchParams.errors)}`));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const { name, icon, tools } = params;
|
|
172
|
+
const cfg = loadConfig();
|
|
173
|
+
const workspaceDir = resolveWorkspaceRoot(cfg);
|
|
174
|
+
const skillDir = path.join(workspaceDir, "skills", name);
|
|
175
|
+
const skillMdPath = path.join(skillDir, "SKILL.md");
|
|
176
|
+
if (!fs.existsSync(skillMdPath)) {
|
|
177
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `Skill not found: ${name}`));
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
const content = fs.readFileSync(skillMdPath, "utf8");
|
|
182
|
+
const fields = {};
|
|
183
|
+
if ("icon" in params)
|
|
184
|
+
fields.icon = icon;
|
|
185
|
+
if ("tools" in params)
|
|
186
|
+
fields.tools = tools;
|
|
187
|
+
const updated = applySkillMetadataFields(content, fields);
|
|
188
|
+
fs.writeFileSync(skillMdPath, updated, "utf8");
|
|
189
|
+
respond(true, { ok: true });
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, String(err)));
|
|
193
|
+
}
|
|
194
|
+
},
|
|
166
195
|
"skills.read": ({ params, respond }) => {
|
|
167
196
|
if (!validateSkillsReadParams(params)) {
|
|
168
197
|
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `invalid skills.read params: ${formatValidationErrors(validateSkillsReadParams.errors)}`));
|
|
@@ -44,6 +44,7 @@ import { brandHandlers } from "./server-methods/brand.js";
|
|
|
44
44
|
import { businessHandlers } from "./server-methods/business.js";
|
|
45
45
|
import { whatsappConversationsHandlers } from "./server-methods/whatsapp-conversations.js";
|
|
46
46
|
import { relayHandlers } from "./server-methods/relay.js";
|
|
47
|
+
import { toolsHandlers } from "./server-methods/tools.js";
|
|
47
48
|
const ADMIN_SCOPE = "operator.admin";
|
|
48
49
|
const READ_SCOPE = "operator.read";
|
|
49
50
|
const WRITE_SCOPE = "operator.write";
|
|
@@ -116,6 +117,7 @@ const READ_METHODS = new Set([
|
|
|
116
117
|
"whatsapp.conversations",
|
|
117
118
|
"whatsapp.messages",
|
|
118
119
|
"whatsapp.groupInfo",
|
|
120
|
+
"tools.list",
|
|
119
121
|
]);
|
|
120
122
|
const WRITE_METHODS = new Set([
|
|
121
123
|
"send",
|
|
@@ -266,6 +268,7 @@ export const coreGatewayHandlers = {
|
|
|
266
268
|
...wifiHandlers,
|
|
267
269
|
...whatsappConversationsHandlers,
|
|
268
270
|
...relayHandlers,
|
|
271
|
+
...toolsHandlers,
|
|
269
272
|
};
|
|
270
273
|
export async function handleGatewayRequest(opts) {
|
|
271
274
|
const { req, respond, client, isWebchatConnect, context } = opts;
|
|
@@ -112,7 +112,11 @@ export function loadSessionEntry(sessionKey) {
|
|
|
112
112
|
const agentId = resolveSessionStoreAgentId(cfg, canonicalKey);
|
|
113
113
|
const storePath = resolveStorePath(sessionCfg?.store, { agentId });
|
|
114
114
|
const store = loadSessionStore(storePath);
|
|
115
|
-
|
|
115
|
+
// Try canonical key first, then fall back to raw key.
|
|
116
|
+
// The runtime's resolveSessionKey stores entries under the raw key (e.g.
|
|
117
|
+
// "webchat:admin:ts") but resolveSessionStoreKey canonicalizes to
|
|
118
|
+
// "agent:admin:webchat:admin:ts". Both forms must be checked.
|
|
119
|
+
const entry = store[canonicalKey] ?? store[sessionKey];
|
|
116
120
|
return { cfg, storePath, store, entry, canonicalKey };
|
|
117
121
|
}
|
|
118
122
|
export function classifySessionKey(key, entry) {
|
|
@@ -43,12 +43,26 @@ export async function applyMediaUnderstanding(params) {
|
|
|
43
43
|
if (decisions.length > 0) {
|
|
44
44
|
ctx.MediaUnderstandingDecisions = [...(ctx.MediaUnderstandingDecisions ?? []), ...decisions];
|
|
45
45
|
}
|
|
46
|
-
// Surface
|
|
47
|
-
// a bare <media:
|
|
46
|
+
// Surface media download failures so the agent can inform the user instead of
|
|
47
|
+
// receiving a bare <media:TYPE> placeholder with no context about what went wrong.
|
|
48
|
+
const bodyHint = ctx.CommandBody ?? ctx.RawBody ?? ctx.Body ?? "";
|
|
49
|
+
const mediaPlaceholderMatch = /^<media:(\w+)>/i.exec(bodyHint.trim());
|
|
50
|
+
const isAudioPlaceholder = mediaPlaceholderMatch?.[1]?.toLowerCase() === "audio";
|
|
51
|
+
if (ctx.MediaDownloadFailed && mediaPlaceholderMatch && !isAudioPlaceholder) {
|
|
52
|
+
const mediaType = mediaPlaceholderMatch[1]?.toLowerCase() ?? "file";
|
|
53
|
+
const reasonSuffix = ctx.MediaDownloadFailedReason
|
|
54
|
+
? ` (${ctx.MediaDownloadFailedReason})`
|
|
55
|
+
: "";
|
|
56
|
+
const note = `[Media download failed — the ${mediaType} could not be retrieved from WhatsApp${reasonSuffix}. Ask the user to resend or share the content directly.]`;
|
|
57
|
+
logVerbose(`applyMediaUnderstanding: ${note}`);
|
|
58
|
+
ctx.Body = note;
|
|
59
|
+
ctx.CommandBody = note;
|
|
60
|
+
ctx.RawBody = note;
|
|
61
|
+
finalizeInboundContext(ctx, { forceBodyForAgent: true, forceBodyForCommands: true });
|
|
62
|
+
}
|
|
63
|
+
// Surface audio failures with more detailed provider-specific reasons.
|
|
48
64
|
const audioDecision = decisions.find((d) => d.capability === "audio");
|
|
49
65
|
const audioTranscribed = outputs.some((o) => o.kind === "audio.transcription");
|
|
50
|
-
const bodyHint = ctx.CommandBody ?? ctx.RawBody ?? ctx.Body ?? "";
|
|
51
|
-
const isAudioPlaceholder = /^<media:audio>/i.test(bodyHint.trim());
|
|
52
66
|
if (isAudioPlaceholder && !audioTranscribed) {
|
|
53
67
|
let reason;
|
|
54
68
|
if (ctx.MediaDownloadFailed) {
|
|
@@ -267,6 +267,7 @@ export async function processMessage(params) {
|
|
|
267
267
|
MediaUrl: params.msg.mediaUrl,
|
|
268
268
|
MediaType: params.msg.mediaType,
|
|
269
269
|
MediaDownloadFailed: params.msg.mediaDownloadFailed,
|
|
270
|
+
MediaDownloadFailedReason: params.msg.mediaDownloadFailedReason,
|
|
270
271
|
ChatType: params.msg.chatType,
|
|
271
272
|
ConversationLabel: params.msg.chatType === "group" ? conversationId : params.msg.from,
|
|
272
273
|
GroupSubject: params.msg.groupSubject,
|
|
@@ -297,6 +297,7 @@ export async function monitorWebInbox(options) {
|
|
|
297
297
|
let mediaPath;
|
|
298
298
|
let mediaType;
|
|
299
299
|
let mediaDownloadFailed = false;
|
|
300
|
+
let mediaDownloadFailedReason;
|
|
300
301
|
try {
|
|
301
302
|
const inboundMedia = await downloadInboundMedia(msg, sock);
|
|
302
303
|
if (inboundMedia) {
|
|
@@ -311,11 +312,13 @@ export async function monitorWebInbox(options) {
|
|
|
311
312
|
else if (body.includes("<media:")) {
|
|
312
313
|
// downloadInboundMedia returned undefined — media was expected but unavailable
|
|
313
314
|
mediaDownloadFailed = true;
|
|
315
|
+
mediaDownloadFailedReason = "media could not be downloaded";
|
|
314
316
|
inboundLogger.warn({ id, from, body }, "media download returned empty");
|
|
315
317
|
}
|
|
316
318
|
}
|
|
317
319
|
catch (err) {
|
|
318
320
|
mediaDownloadFailed = body.includes("<media:");
|
|
321
|
+
mediaDownloadFailedReason = String(err).replace(/^Error:\s*/, "");
|
|
319
322
|
inboundLogger.warn({ id, from, error: String(err) }, "media download failed");
|
|
320
323
|
}
|
|
321
324
|
const chatJid = remoteJid;
|
|
@@ -378,6 +381,7 @@ export async function monitorWebInbox(options) {
|
|
|
378
381
|
mediaPath,
|
|
379
382
|
mediaType,
|
|
380
383
|
mediaDownloadFailed,
|
|
384
|
+
mediaDownloadFailedReason,
|
|
381
385
|
businessClosed,
|
|
382
386
|
};
|
|
383
387
|
try {
|
package/package.json
CHANGED
|
@@ -60,16 +60,30 @@ For each reference file:
|
|
|
60
60
|
|
|
61
61
|
If the skill is simple enough to fit in SKILL.md alone (under ~30 lines of instructions), skip references.
|
|
62
62
|
|
|
63
|
-
## Step 5:
|
|
63
|
+
## Step 5: Choose an Icon
|
|
64
|
+
|
|
65
|
+
Ask: **"Would you like to pick an icon for this skill?"**
|
|
66
|
+
|
|
67
|
+
Icons give skills a visual identity in the Control Panel. They use [Lucide](https://lucide.dev) icon names. Offer a few suggestions that match the skill's purpose — the reference file `references/lean-pattern.md` has the full curated list.
|
|
68
|
+
|
|
69
|
+
If the user picks one, include `"icon": "<name>"` in the `metadata.taskmaster` block in frontmatter. If they skip this, omit the field — it's optional.
|
|
70
|
+
|
|
71
|
+
## Step 5b: Identify Required Tools
|
|
72
|
+
|
|
73
|
+
If the skill needs specific agent tools (web search, memory, file access, etc.), note them. This matters when the skill will be assigned to a sub-agent — sub-agents have restricted tool access, so the skill must declare which tools it needs via the `tools` field in `metadata.taskmaster`.
|
|
74
|
+
|
|
75
|
+
For skills on the primary agent, tools are already available and this field is unnecessary. Only add `tools` when the user indicates the skill targets a sub-agent.
|
|
76
|
+
|
|
77
|
+
## Step 6: Compose the Skill
|
|
64
78
|
|
|
65
79
|
Using the lean pattern from `references/lean-pattern.md`, compose:
|
|
66
80
|
|
|
67
|
-
1. **SKILL.md** — frontmatter (`name`, `description`) + activation conditions + behaviour rules + references index
|
|
81
|
+
1. **SKILL.md** — frontmatter (`name`, `description`, optional `metadata.taskmaster` with `icon`/`tools`) + activation conditions + behaviour rules + references index
|
|
68
82
|
2. **Reference files** — one per detailed topic
|
|
69
83
|
|
|
70
84
|
Show the user the complete SKILL.md content and each reference file. Ask them to review.
|
|
71
85
|
|
|
72
|
-
## Step
|
|
86
|
+
## Step 7: Save the Draft
|
|
73
87
|
|
|
74
88
|
Use the `skill_draft_save` tool:
|
|
75
89
|
|
|
@@ -85,7 +99,7 @@ skill_draft_save({
|
|
|
85
99
|
|
|
86
100
|
The tool saves the draft to the correct location where the Control Panel looks for drafts. Do not use `memory_write` or `write` — those save to the wrong location.
|
|
87
101
|
|
|
88
|
-
## Step
|
|
102
|
+
## Step 8: Direct to Control Panel
|
|
89
103
|
|
|
90
104
|
Tell the user:
|
|
91
105
|
|
|
@@ -55,18 +55,28 @@ Load `references/templates.md` for [what it covers].
|
|
|
55
55
|
## Optional Frontmatter Fields
|
|
56
56
|
|
|
57
57
|
```yaml
|
|
58
|
-
metadata: {"taskmaster":{"always":true,"emoji":"📦","primaryEnv":"MY_API_KEY"}}
|
|
58
|
+
metadata: {"taskmaster":{"always":true,"icon":"Calendar","emoji":"📦","primaryEnv":"MY_API_KEY"}}
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
| Field | Purpose |
|
|
62
62
|
|-------|---------|
|
|
63
63
|
| `always` | Always include in prompt (skip eligibility checks) |
|
|
64
|
-
| `
|
|
64
|
+
| `icon` | Lucide icon name displayed in the Control Panel skill card. Gives the skill a recognisable visual identity. See icon list below. |
|
|
65
|
+
| `emoji` | Fallback display emoji — used only when no `icon` is set |
|
|
65
66
|
| `primaryEnv` | Env var for API key — enables the key input field in the UI |
|
|
67
|
+
| `tools` | Array of tool names the skill needs (e.g. `["web_search", "memory_write"]`). When a skill is assigned to a sub-agent, the tools listed here are made available to that agent. Only relevant for skills that will run on sub-agents with restricted tool access. |
|
|
66
68
|
| `requires.bins` | Required binaries (e.g. `["curl"]`) |
|
|
67
69
|
| `requires.env` | Required environment variables |
|
|
68
70
|
|
|
69
|
-
Most user-created skills need only `name` and `description`.
|
|
71
|
+
Most user-created skills need only `name` and `description`. Add `icon` for a polished look in the Control Panel.
|
|
72
|
+
|
|
73
|
+
### Available Icon Names
|
|
74
|
+
|
|
75
|
+
These are [Lucide](https://lucide.dev) icon names. Choose one that reflects the skill's purpose:
|
|
76
|
+
|
|
77
|
+
`Zap` · `Globe` · `BookOpen` · `Calendar` · `Camera` · `Clock` · `Cloud` · `Code` · `Database` · `FileText` · `Headphones` · `Heart` · `Home` · `Image` · `Mail` · `Map` · `MessageSquare` · `Music` · `Phone` · `Puzzle` · `Search` · `Settings` · `ShoppingCart` · `Star` · `Tag` · `Truck` · `User` · `Wallet` · `Wrench` · `Cpu`
|
|
78
|
+
|
|
79
|
+
Any valid Lucide icon name works — this list is a starting point, not a constraint.
|
|
70
80
|
|
|
71
81
|
## Examples
|
|
72
82
|
|