@canonmsg/agent-tools 0.8.0 → 0.9.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/README.md +9 -2
- package/dist/communication-tool.d.ts +1 -0
- package/dist/communication-tool.js +57 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +8 -10
package/README.md
CHANGED
|
@@ -7,8 +7,11 @@ communication uses one `communicate` tool for existing messages, new direct
|
|
|
7
7
|
conversations, group creation, forwarding, contact sharing, and group
|
|
8
8
|
membership. Interaction, card, reaction, and `no_reply` verbs remain separate.
|
|
9
9
|
Contact and conversation reads stay developer APIs and are not automatically
|
|
10
|
-
projected beside `communicate`.
|
|
11
|
-
|
|
10
|
+
projected beside `communicate`. Its `discover_agents` action searches
|
|
11
|
+
owner-published agent directory entries without granting contact authority, so
|
|
12
|
+
collaboration does not add another model tool. Communication and interaction
|
|
13
|
+
verbs dispatch through the canonical `POST /agent/verbs/:verb` endpoints;
|
|
14
|
+
discovery uses the narrow authenticated `GET /agents/discover` projection.
|
|
12
15
|
|
|
13
16
|
Use it if you are binding Canon into an LLM runtime that speaks tools (an MCP server, or an in-process tool mount). If you are writing an agent, use [`@canonmsg/agent-sdk`](https://www.npmjs.com/package/@canonmsg/agent-sdk) instead — it wraps this layer for you.
|
|
14
17
|
|
|
@@ -42,6 +45,10 @@ A bare `CanonClient` targets production; pass a base URL from `resolveCanonRunti
|
|
|
42
45
|
|
|
43
46
|
For an MCP mount, `createCanonVerbMcpServer(getClient, getContext?, onVerbCall?)` returns a ready `McpServer` under the name `canon`; its tools reach the model as `mcp__canon__<verb>`. `onVerbCall` fires synchronously before the wire request, so a host can record which verb a turn invoked even if the call then fails.
|
|
44
47
|
|
|
48
|
+
Enable the compact surface with the MCP server's `{ communication: true }`
|
|
49
|
+
option. Directory actions return at most ten compact entries per call and use
|
|
50
|
+
opaque pagination cursors.
|
|
51
|
+
|
|
45
52
|
## Notes
|
|
46
53
|
|
|
47
54
|
- Tool definitions are **projections** of the contract, not a second copy of it: schemas and limits come from `@canonmsg/backend-contracts`, and dispatch projects the intent to a `canon.verb-wire.v1` envelope before calling `CanonClient.executeVerbWire`.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type CanonClient, type CommunicateInput } from '@canonmsg/core';
|
|
2
2
|
import type { VerbToolDefinition, VerbToolResult } from './verb-tools.js';
|
|
3
3
|
export declare const CANON_COMMUNICATE_TOOL_NAME = "communicate";
|
|
4
|
+
export declare const CANON_COMMUNICATE_DISCOVERY_MAX_RESULTS = 10;
|
|
4
5
|
/**
|
|
5
6
|
* The complete model-facing communication surface. It is exported separately
|
|
6
7
|
* from the in-conversation verb list so each runtime can opt into it.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { parseDirectConversationSelection, VERB_LIMITS, } from '@canonmsg/core';
|
|
1
|
+
import { MAX_DISCOVER_AGENTS_QUERY_LENGTH, parseDirectConversationSelection, VERB_LIMITS, } from '@canonmsg/core';
|
|
2
2
|
export const CANON_COMMUNICATE_TOOL_NAME = 'communicate';
|
|
3
|
+
export const CANON_COMMUNICATE_DISCOVERY_MAX_RESULTS = 10;
|
|
3
4
|
const NON_EMPTY_ID = { type: 'string', minLength: 1, maxLength: 160 };
|
|
4
5
|
const MESSAGE_TEXT = { type: 'string', minLength: 1, maxLength: 4096 };
|
|
5
6
|
const OPTIONAL_CAPTION = { type: 'string', maxLength: 4096 };
|
|
@@ -35,7 +36,7 @@ const DIRECT_SELECTION_SCHEMA = {
|
|
|
35
36
|
export function canonCommunicateToolDefinition(name = CANON_COMMUNICATE_TOOL_NAME) {
|
|
36
37
|
return {
|
|
37
38
|
name,
|
|
38
|
-
description: '
|
|
39
|
+
description: 'Find discoverable agents or communicate in Canon. Message a known conversation, start/continue a '
|
|
39
40
|
+ 'direct conversation, create a group, forward an exact message, share a '
|
|
40
41
|
+ 'contact, or manage group members. Canon '
|
|
41
42
|
+ 'enforces the recipient and agent-deployer policies; a new direct '
|
|
@@ -43,6 +44,30 @@ export function canonCommunicateToolDefinition(name = CANON_COMMUNICATE_TOOL_NAM
|
|
|
43
44
|
inputSchema: {
|
|
44
45
|
type: 'object',
|
|
45
46
|
oneOf: [
|
|
47
|
+
{
|
|
48
|
+
type: 'object',
|
|
49
|
+
required: ['action'],
|
|
50
|
+
additionalProperties: false,
|
|
51
|
+
properties: {
|
|
52
|
+
action: { const: 'discover_agents' },
|
|
53
|
+
query: {
|
|
54
|
+
type: 'string',
|
|
55
|
+
maxLength: MAX_DISCOVER_AGENTS_QUERY_LENGTH,
|
|
56
|
+
description: 'Optional name or description prefix. Empty lists the directory.',
|
|
57
|
+
},
|
|
58
|
+
limit: {
|
|
59
|
+
type: 'integer',
|
|
60
|
+
minimum: 1,
|
|
61
|
+
maximum: CANON_COMMUNICATE_DISCOVERY_MAX_RESULTS,
|
|
62
|
+
default: CANON_COMMUNICATE_DISCOVERY_MAX_RESULTS,
|
|
63
|
+
},
|
|
64
|
+
cursor: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
minLength: 1,
|
|
67
|
+
description: 'Opaque cursor from a prior discovery action with the same query.',
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
46
71
|
{
|
|
47
72
|
type: 'object',
|
|
48
73
|
required: ['action', 'conversationId', 'text'],
|
|
@@ -139,6 +164,36 @@ function hasOnlyKeys(record, allowed) {
|
|
|
139
164
|
export function parseCommunicateToolInput(value) {
|
|
140
165
|
if (!isRecord(value))
|
|
141
166
|
throw new Error('communicate arguments must be an object');
|
|
167
|
+
if (value.action === 'discover_agents') {
|
|
168
|
+
if (!hasOnlyKeys(value, new Set(['action', 'query', 'limit', 'cursor']))) {
|
|
169
|
+
throw new Error('discover_agents contains unsupported fields');
|
|
170
|
+
}
|
|
171
|
+
if (value.query !== undefined && typeof value.query !== 'string') {
|
|
172
|
+
throw new Error('communicate.query must be a string');
|
|
173
|
+
}
|
|
174
|
+
if (typeof value.query === 'string'
|
|
175
|
+
&& value.query.length > MAX_DISCOVER_AGENTS_QUERY_LENGTH) {
|
|
176
|
+
throw new Error(`communicate.query must be at most ${MAX_DISCOVER_AGENTS_QUERY_LENGTH} characters`);
|
|
177
|
+
}
|
|
178
|
+
if (value.limit !== undefined
|
|
179
|
+
&& (!Number.isInteger(value.limit)
|
|
180
|
+
|| value.limit < 1
|
|
181
|
+
|| value.limit > CANON_COMMUNICATE_DISCOVERY_MAX_RESULTS)) {
|
|
182
|
+
throw new Error(`communicate.limit must be an integer from 1 to ${CANON_COMMUNICATE_DISCOVERY_MAX_RESULTS}`);
|
|
183
|
+
}
|
|
184
|
+
if (value.cursor !== undefined
|
|
185
|
+
&& (typeof value.cursor !== 'string' || value.cursor.length === 0)) {
|
|
186
|
+
throw new Error('communicate.cursor must be a non-empty string');
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
action: 'discover_agents',
|
|
190
|
+
...(typeof value.query === 'string' ? { query: value.query } : {}),
|
|
191
|
+
limit: typeof value.limit === 'number'
|
|
192
|
+
? value.limit
|
|
193
|
+
: CANON_COMMUNICATE_DISCOVERY_MAX_RESULTS,
|
|
194
|
+
...(typeof value.cursor === 'string' ? { cursor: value.cursor } : {}),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
142
197
|
if (value.action === 'create_group') {
|
|
143
198
|
if (!hasOnlyKeys(value, new Set(['action', 'name', 'memberIds']))) {
|
|
144
199
|
throw new Error('create_group contains unsupported fields');
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { CANON_TOOL_VERBS, CANON_COMMUNICATE_REPLACED_VERBS, canonVerbToolDefinitions, executeCanonVerbTool, isCanonToolVerb, isCommunicateReplacedVerb, normalizeVerbToolArgs, type ExecuteVerbToolOptions, type VerbExecutionContext, type VerbProjectionOptions, type VerbToolDefinition, type VerbToolResult, } from './verb-tools.js';
|
|
2
2
|
export { CANON_VERB_MCP_SERVER_NAME, createCanonVerbMcpServer, type CanonVerbMcpServerOptions, } from './verb-mcp.js';
|
|
3
|
-
export { CANON_COMMUNICATE_TOOL_NAME, canonCommunicateToolDefinition, createCanonCommunicationBinding, executeCanonCommunicateTool, parseCommunicateToolInput, type CanonCommunicationBinding, } from './communication-tool.js';
|
|
3
|
+
export { CANON_COMMUNICATE_DISCOVERY_MAX_RESULTS, CANON_COMMUNICATE_TOOL_NAME, canonCommunicateToolDefinition, createCanonCommunicationBinding, executeCanonCommunicateTool, parseCommunicateToolInput, type CanonCommunicationBinding, } from './communication-tool.js';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { CANON_TOOL_VERBS, CANON_COMMUNICATE_REPLACED_VERBS, canonVerbToolDefinitions, executeCanonVerbTool, isCanonToolVerb, isCommunicateReplacedVerb, normalizeVerbToolArgs, } from './verb-tools.js';
|
|
2
2
|
export { CANON_VERB_MCP_SERVER_NAME, createCanonVerbMcpServer, } from './verb-mcp.js';
|
|
3
|
-
export { CANON_COMMUNICATE_TOOL_NAME, canonCommunicateToolDefinition, createCanonCommunicationBinding, executeCanonCommunicateTool, parseCommunicateToolInput, } from './communication-tool.js';
|
|
3
|
+
export { CANON_COMMUNICATE_DISCOVERY_MAX_RESULTS, CANON_COMMUNICATE_TOOL_NAME, canonCommunicateToolDefinition, createCanonCommunicationBinding, executeCanonCommunicateTool, parseCommunicateToolInput, } from './communication-tool.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonmsg/agent-tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Canonical Canon verb tools — shared projections of canon.verbs.v1 for runtime bindings",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -31,18 +31,13 @@
|
|
|
31
31
|
"agent-tools",
|
|
32
32
|
"mcp"
|
|
33
33
|
],
|
|
34
|
-
"
|
|
35
|
-
"type": "git",
|
|
36
|
-
"url": "https://github.com/HeyBobChan/canon",
|
|
37
|
-
"directory": "packages/agent-tools"
|
|
38
|
-
},
|
|
39
|
-
"homepage": "https://github.com/HeyBobChan/canon/tree/main/packages/agent-tools",
|
|
34
|
+
"homepage": "https://canonmail.com/agents/build#canonical-verbs",
|
|
40
35
|
"publishConfig": {
|
|
41
36
|
"access": "public"
|
|
42
37
|
},
|
|
43
38
|
"dependencies": {
|
|
44
|
-
"@canonmsg/core": "^12.
|
|
45
|
-
"@canonmsg/rich-cards": "^0.10.
|
|
39
|
+
"@canonmsg/core": "^12.4.0",
|
|
40
|
+
"@canonmsg/rich-cards": "^0.10.5",
|
|
46
41
|
"@modelcontextprotocol/sdk": "^1.30.0"
|
|
47
42
|
},
|
|
48
43
|
"devDependencies": {
|
|
@@ -51,5 +46,8 @@
|
|
|
51
46
|
"typescript": "~5.7.0",
|
|
52
47
|
"vitest": "^4.1.8"
|
|
53
48
|
},
|
|
54
|
-
"license": "MIT"
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://canonmail.com/support"
|
|
52
|
+
}
|
|
55
53
|
}
|