@intx/tools-mail 0.2.2 → 0.4.0
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 +5 -1
- package/dist/definitions.d.ts +1 -1
- package/dist/definitions.js +39 -1
- package/dist/handlers.d.ts +2 -0
- package/dist/handlers.js +75 -4
- package/dist/index.js +5 -3
- package/dist/sidecar-bundle.d.ts +4 -5
- package/dist/sidecar-bundle.js +10 -10
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -14,7 +14,11 @@ its definitions alongside other bundles.
|
|
|
14
14
|
import { createMailTools } from "@intx/tools-mail";
|
|
15
15
|
import { defineMailTools } from "@intx/harness";
|
|
16
16
|
|
|
17
|
-
const
|
|
17
|
+
const mailTools = createMailTools({ capabilities });
|
|
18
|
+
const mailFactory = defineMailTools(
|
|
19
|
+
() => mailTools,
|
|
20
|
+
mailTools.definitions.map((def) => ({ name: def.name })),
|
|
21
|
+
);
|
|
18
22
|
const def = defineAgent({ ..., tools: [mailFactory, posixFactory] });
|
|
19
23
|
```
|
|
20
24
|
|
package/dist/definitions.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { ToolDefinition } from "@intx/types/runtime";
|
|
2
|
-
export type MailToolName = "mail_send" | "mail_reply" | "mail_search" | "mail_read" | "mail_wait";
|
|
2
|
+
export type MailToolName = "mail_send" | "mail_reply" | "mail_search" | "mail_read" | "mail_wait" | "mail_flag" | "mail_expunge";
|
|
3
3
|
export declare const TOOL_DEFINITIONS: ToolDefinition[];
|
package/dist/definitions.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Static definitions for the
|
|
1
|
+
// Static definitions for the mail tools. The catalog generator and the
|
|
2
2
|
// inference director both consume these as inert data — no factory calls,
|
|
3
3
|
// no runtime side effects.
|
|
4
4
|
//
|
|
@@ -134,4 +134,42 @@ export const TOOL_DEFINITIONS = [
|
|
|
134
134
|
required: ["query"],
|
|
135
135
|
},
|
|
136
136
|
},
|
|
137
|
+
{
|
|
138
|
+
name: "mail_flag",
|
|
139
|
+
description: "Set or clear IMAP flags on a message (system flags like \\Seen or \\Deleted, or custom keywords). Provide EITHER 'set' to add flags OR 'clear' to remove them -- one direction per call. To consume a message, flag it \\Deleted then call mail_expunge. An error result means the mailbox was NOT changed.",
|
|
140
|
+
inputSchema: {
|
|
141
|
+
type: "object",
|
|
142
|
+
properties: {
|
|
143
|
+
ref: {
|
|
144
|
+
type: "object",
|
|
145
|
+
description: "Mail reference { uid, mailbox }",
|
|
146
|
+
properties: {
|
|
147
|
+
uid: { type: "number" },
|
|
148
|
+
mailbox: { type: "string" },
|
|
149
|
+
},
|
|
150
|
+
required: ["uid", "mailbox"],
|
|
151
|
+
},
|
|
152
|
+
set: {
|
|
153
|
+
type: "array",
|
|
154
|
+
items: { type: "string" },
|
|
155
|
+
description: 'Flags to add (e.g. ["\\\\Deleted"])',
|
|
156
|
+
},
|
|
157
|
+
clear: {
|
|
158
|
+
type: "array",
|
|
159
|
+
items: { type: "string" },
|
|
160
|
+
description: "Flags to remove",
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
required: ["ref"],
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name: "mail_expunge",
|
|
168
|
+
description: "Permanently remove every message flagged \\Deleted from the INBOX and return the uids removed. Flag a message \\Deleted with mail_flag first. An error result means nothing was removed.",
|
|
169
|
+
inputSchema: {
|
|
170
|
+
type: "object",
|
|
171
|
+
properties: {},
|
|
172
|
+
required: [],
|
|
173
|
+
},
|
|
174
|
+
},
|
|
137
175
|
];
|
package/dist/handlers.d.ts
CHANGED
|
@@ -5,3 +5,5 @@ export declare function makeMailReplyHandler(transport: MessageTransport): ToolH
|
|
|
5
5
|
export declare function makeMailSearchHandler(transport: MessageTransport): ToolHandler;
|
|
6
6
|
export declare function makeMailReadHandler(transport: MessageTransport): ToolHandler;
|
|
7
7
|
export declare function makeMailWaitHandler(transport: MessageTransport): ToolHandler;
|
|
8
|
+
export declare function makeMailFlagHandler(transport: MessageTransport): ToolHandler;
|
|
9
|
+
export declare function makeMailExpungeHandler(transport: MessageTransport): ToolHandler;
|
package/dist/handlers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Per-tool handler factories for the
|
|
1
|
+
// Per-tool handler factories for the mail tools. Each factory takes
|
|
2
2
|
// the bound MessageTransport and returns a closed-over ToolHandler.
|
|
3
3
|
//
|
|
4
4
|
// Keeping the factories at this granularity (one per tool, pure
|
|
@@ -42,6 +42,12 @@ const WaitArgs = type({
|
|
|
42
42
|
"timeout?": "number",
|
|
43
43
|
"mailbox?": "string",
|
|
44
44
|
});
|
|
45
|
+
const FlagArgs = type({
|
|
46
|
+
ref: { uid: "number", mailbox: "string" },
|
|
47
|
+
"set?": "string[]",
|
|
48
|
+
"clear?": "string[]",
|
|
49
|
+
});
|
|
50
|
+
const ExpungeArgs = type({});
|
|
45
51
|
// ---------------------------------------------------------------------------
|
|
46
52
|
// Individual tool handlers
|
|
47
53
|
// ---------------------------------------------------------------------------
|
|
@@ -104,6 +110,15 @@ export function makeMailReplyHandler(transport) {
|
|
|
104
110
|
to: parentHeaders.from,
|
|
105
111
|
type: args.type ?? "conversation.message",
|
|
106
112
|
inReplyTo: parentHeaders.messageId,
|
|
113
|
+
// The full RFC 5322 References chain for a reply is the parent's own
|
|
114
|
+
// References plus the parent's Message-Id. The parent is in hand here
|
|
115
|
+
// (fetched above for its threading headers), so build the complete
|
|
116
|
+
// ancestry rather than leaving the transport to derive a single-element
|
|
117
|
+
// chain from inReplyTo alone.
|
|
118
|
+
references: [
|
|
119
|
+
...(parentHeaders.references ?? []),
|
|
120
|
+
parentHeaders.messageId,
|
|
121
|
+
],
|
|
107
122
|
};
|
|
108
123
|
// Carry forward the subject if available.
|
|
109
124
|
if (parentHeaders.subject !== undefined) {
|
|
@@ -115,9 +130,6 @@ export function makeMailReplyHandler(transport) {
|
|
|
115
130
|
if (payload !== undefined) {
|
|
116
131
|
outbound.payload = payload;
|
|
117
132
|
}
|
|
118
|
-
// OutboundMessage does not carry a References field; the transport
|
|
119
|
-
// builds the threading chain from inReplyTo when delivering the
|
|
120
|
-
// reply.
|
|
121
133
|
let receipt;
|
|
122
134
|
try {
|
|
123
135
|
receipt = await transport.send(outbound, signal);
|
|
@@ -317,6 +329,65 @@ export function makeMailWaitHandler(transport) {
|
|
|
317
329
|
});
|
|
318
330
|
};
|
|
319
331
|
}
|
|
332
|
+
export function makeMailFlagHandler(transport) {
|
|
333
|
+
return async (call, signal) => {
|
|
334
|
+
const args = FlagArgs(call.arguments);
|
|
335
|
+
if (args instanceof type.errors) {
|
|
336
|
+
return errorResult(call.id, args.summary);
|
|
337
|
+
}
|
|
338
|
+
const set = args.set ?? [];
|
|
339
|
+
const clear = args.clear ?? [];
|
|
340
|
+
// Reject an empty mutation at the boundary: a call with neither direction
|
|
341
|
+
// does nothing, and firing an empty flag write would still round-trip to
|
|
342
|
+
// the supervisor as a pointless commit.
|
|
343
|
+
if (set.length === 0 && clear.length === 0) {
|
|
344
|
+
return errorResult(call.id, "provide flags in 'set' or 'clear'");
|
|
345
|
+
}
|
|
346
|
+
// One direction per call. Adding and removing flags in one call would be
|
|
347
|
+
// two separate supervisor round-trips; if the first landed and the second
|
|
348
|
+
// failed, the error's "mailbox unchanged" contract would be a lie. Keeping
|
|
349
|
+
// each call a single mutation makes that contract unconditionally true.
|
|
350
|
+
if (set.length > 0 && clear.length > 0) {
|
|
351
|
+
return errorResult(call.id, "provide 'set' or 'clear', not both -- call mail_flag once per direction");
|
|
352
|
+
}
|
|
353
|
+
try {
|
|
354
|
+
if (set.length > 0) {
|
|
355
|
+
await transport.setFlags(args.ref, set, signal);
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
await transport.clearFlags(args.ref, clear, signal);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
catch (cause) {
|
|
362
|
+
// A rejection means the supervisor did not apply the mutation, so the
|
|
363
|
+
// mailbox is unchanged. Surface that so the model does not assume the
|
|
364
|
+
// flag stuck (and then expunge expecting the message gone).
|
|
365
|
+
return errorResult(call.id, `flag not applied: ${cause instanceof Error ? cause.message : String(cause)}`, "flag_failed");
|
|
366
|
+
}
|
|
367
|
+
return { callId: call.id, content: { ok: true } };
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
export function makeMailExpungeHandler(transport) {
|
|
371
|
+
return async (call, signal) => {
|
|
372
|
+
const args = ExpungeArgs(call.arguments);
|
|
373
|
+
if (args instanceof type.errors) {
|
|
374
|
+
return errorResult(call.id, args.summary);
|
|
375
|
+
}
|
|
376
|
+
// The warm agent owns exactly one mailbox; expunge sweeps its INBOX.
|
|
377
|
+
let outcome;
|
|
378
|
+
try {
|
|
379
|
+
outcome = await transport.expunge("INBOX", signal);
|
|
380
|
+
}
|
|
381
|
+
catch (cause) {
|
|
382
|
+
// A rejection means nothing was removed; the mailbox is unchanged.
|
|
383
|
+
return errorResult(call.id, `expunge not applied: ${cause instanceof Error ? cause.message : String(cause)}`, "expunge_failed");
|
|
384
|
+
}
|
|
385
|
+
return {
|
|
386
|
+
callId: call.id,
|
|
387
|
+
content: { ok: true, expungedUids: outcome.expungedUids },
|
|
388
|
+
};
|
|
389
|
+
};
|
|
390
|
+
}
|
|
320
391
|
// ---------------------------------------------------------------------------
|
|
321
392
|
// Helper
|
|
322
393
|
// ---------------------------------------------------------------------------
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// Public surface for @intx/tools-mail.
|
|
2
2
|
//
|
|
3
3
|
// createMailTools resolves the bound agent's MessageTransport from the
|
|
4
|
-
// supplied RuntimeCapabilities once at handler-init and wires the
|
|
5
|
-
//
|
|
4
|
+
// supplied RuntimeCapabilities once at handler-init and wires the mail
|
|
5
|
+
// handlers around it. The returned MailTools satisfies the
|
|
6
6
|
// ToolRunner contract the harness consumes.
|
|
7
7
|
import { TOOL_DEFINITIONS } from "./definitions.js";
|
|
8
|
-
import { makeMailReadHandler, makeMailReplyHandler, makeMailSearchHandler, makeMailSendHandler, makeMailWaitHandler, } from "./handlers.js";
|
|
8
|
+
import { makeMailExpungeHandler, makeMailFlagHandler, makeMailReadHandler, makeMailReplyHandler, makeMailSearchHandler, makeMailSendHandler, makeMailWaitHandler, } from "./handlers.js";
|
|
9
9
|
export { TOOL_DEFINITIONS } from "./definitions.js";
|
|
10
10
|
export function createMailTools(opts) {
|
|
11
11
|
// Resolve the transport once at handler-init. The lifecycle contract is
|
|
@@ -19,6 +19,8 @@ export function createMailTools(opts) {
|
|
|
19
19
|
["mail_search", makeMailSearchHandler(transport)],
|
|
20
20
|
["mail_read", makeMailReadHandler(transport)],
|
|
21
21
|
["mail_wait", makeMailWaitHandler(transport)],
|
|
22
|
+
["mail_flag", makeMailFlagHandler(transport)],
|
|
23
|
+
["mail_expunge", makeMailExpungeHandler(transport)],
|
|
22
24
|
]);
|
|
23
25
|
let disposed = false;
|
|
24
26
|
return {
|
package/dist/sidecar-bundle.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { type BaseEnv } from "@intx/agent";
|
|
2
|
-
import type {
|
|
2
|
+
import type { RuntimeCapabilities } from "@intx/types/runtime-capabilities";
|
|
3
3
|
/**
|
|
4
4
|
* Env contract for the mail tool bundle. Extends `BaseEnv` with the
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* that already provides that env can pass it straight through.
|
|
5
|
+
* host-assembled `capabilities` -- from which the mail tools resolve
|
|
6
|
+
* `mail.transport` -- and the agent `address`.
|
|
8
7
|
*/
|
|
9
8
|
export interface MailToolEnv extends BaseEnv {
|
|
10
|
-
|
|
9
|
+
capabilities: RuntimeCapabilities;
|
|
11
10
|
address: string;
|
|
12
11
|
}
|
|
13
12
|
/**
|
package/dist/sidecar-bundle.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
// Sidecar-bundle entry for `@intx/tools-mail` — the convention-compliant
|
|
2
2
|
// factory the tool-package loader invokes.
|
|
3
3
|
//
|
|
4
|
-
// The
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
4
|
+
// The bundle consumes the host-assembled runtime capabilities rather than
|
|
5
|
+
// building its own. The host (the sidecar's step-env builder) owns the
|
|
6
|
+
// `RuntimeCapabilities` and puts it on `env.capabilities`; this factory
|
|
7
|
+
// resolves `mail.transport` from it through `createMailTools` instead of
|
|
8
|
+
// re-wrapping a raw transport it was handed separately. The env keys it
|
|
9
|
+
// touches (`capabilities`, `address`) are declared in `requires`.
|
|
8
10
|
import { defineTool } from "@intx/agent";
|
|
9
|
-
import { createRuntimeCapabilities } from "@intx/types/runtime-capabilities";
|
|
10
11
|
import { createMailTools } from "./index.js";
|
|
12
|
+
import { TOOL_DEFINITIONS } from "./definitions.js";
|
|
11
13
|
/**
|
|
12
14
|
* Named export the loader picks up. The id is package-namespaced per
|
|
13
15
|
* the convention; the model-facing tool names are synthesized by the
|
|
@@ -15,12 +17,10 @@ import { createMailTools } from "./index.js";
|
|
|
15
17
|
*/
|
|
16
18
|
export const mail = defineTool({
|
|
17
19
|
id: "@intx/tools-mail/sidecar-bundle",
|
|
18
|
-
requires: ["
|
|
20
|
+
requires: ["capabilities", "address"],
|
|
21
|
+
definitions: TOOL_DEFINITIONS.map((def) => ({ name: def.name })),
|
|
19
22
|
factory: (env) => {
|
|
20
|
-
const
|
|
21
|
-
"mail.transport": env.transport,
|
|
22
|
-
});
|
|
23
|
-
const tools = createMailTools({ capabilities });
|
|
23
|
+
const tools = createMailTools({ capabilities: env.capabilities });
|
|
24
24
|
return {
|
|
25
25
|
definitions: tools.definitions,
|
|
26
26
|
run: (call, signal) => tools.run(call, signal),
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intx/tools-mail",
|
|
3
|
-
"
|
|
3
|
+
"description": "Mail tool runner giving agents mail_send, mail_reply, mail_search, mail_read, and mail_wait",
|
|
4
|
+
"version": "0.4.0",
|
|
4
5
|
"license": "LGPL-2.1-only",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"interchange": {
|
|
@@ -19,10 +20,13 @@
|
|
|
19
20
|
}
|
|
20
21
|
},
|
|
21
22
|
"dependencies": {
|
|
22
|
-
"@intx/agent": "0.
|
|
23
|
-
"@intx/types": "0.
|
|
23
|
+
"@intx/agent": "0.4.0",
|
|
24
|
+
"@intx/types": "0.4.0",
|
|
24
25
|
"arktype": "^2.1.29"
|
|
25
26
|
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@intx/storage-isogit": "0.4.0"
|
|
29
|
+
},
|
|
26
30
|
"files": [
|
|
27
31
|
"dist",
|
|
28
32
|
"README.md",
|