@5ss/ai-tools 2.11.4 → 3.0.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/CHANGELOG.md +2 -0
- package/README.md +1 -1
- package/dist/imessage-CH49-sFn.js +558 -0
- package/dist/imessage-CH49-sFn.js.map +1 -0
- package/dist/modules/messaging/index.d.ts +12 -24
- package/dist/modules/messaging/index.d.ts.map +1 -1
- package/dist/modules/messaging/index.js +23 -38
- package/dist/modules/messaging/index.js.map +1 -1
- package/dist/vendors/imessage/index.d.ts +65 -188
- package/dist/vendors/imessage/index.d.ts.map +1 -1
- package/dist/vendors/imessage/index.js +2 -2
- package/package.json +2 -18
- package/dist/imessage-CofjmONG.js +0 -893
- package/dist/imessage-CofjmONG.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,8 @@ All notable changes to `@5ss/ai-tools` are documented here.
|
|
|
4
4
|
|
|
5
5
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Releases are cut by [semantic-release](https://semantic-release.gitbook.io/) from [conventional commits](https://www.conventionalcommits.org/).
|
|
6
6
|
|
|
7
|
+
## [3.0.0](https://github.com/five-star-solutions-co/ai-tools/compare/v2.11.4...v3.0.0) (2026-08-10)
|
|
8
|
+
|
|
7
9
|
## [2.11.4](https://github.com/five-star-solutions-co/ai-tools/compare/v2.11.3...v2.11.4) (2026-08-10)
|
|
8
10
|
|
|
9
11
|
## [2.11.3](https://github.com/five-star-solutions-co/ai-tools/compare/v2.11.2...v2.11.3) (2026-08-10)
|
package/README.md
CHANGED
|
@@ -145,7 +145,7 @@ defineTool / defineModule
|
|
|
145
145
|
| `@5ss/ai-tools/telegram` | `telegram-send-text`, `-edit-text`, media, reactions, … | [telegram](./docs/vendors/telegram.md) |
|
|
146
146
|
| `@5ss/ai-tools/slack` | `slack-send-text`, edit, media, reactions, files, … | [slack](./docs/vendors/slack.md) |
|
|
147
147
|
| `@5ss/ai-tools/teams` | `teams-send-text`, edit, media, Bot Framework activities | [teams](./docs/vendors/teams.md) |
|
|
148
|
-
| `@5ss/ai-tools/imessage` | send/edit/react/unsend/read via
|
|
148
|
+
| `@5ss/ai-tools/imessage` | send/edit/react/unsend/read via photon-rest-proxy (HTTP) | [imessage](./docs/vendors/imessage.md) |
|
|
149
149
|
| `@5ss/ai-tools/s3` | `s3-*` (+ signed URL, multipart) | [s3](./docs/vendors/s3.md) |
|
|
150
150
|
| `@5ss/ai-tools/sqs` | `sqs-send`, `-receive`, `-delete`, `-change-visibility` | [sqs](./docs/vendors/sqs.md) |
|
|
151
151
|
| `@5ss/ai-tools/qdrant` | `qdrant-upsert`, `-query`, `-delete` | [qdrant](./docs/vendors/qdrant.md) |
|
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
import { t as ToolError } from "./errors-DoSpNHvs.js";
|
|
2
|
+
import { n as defineModule, r as defineTool } from "./define-ieoksEQ0.js";
|
|
3
|
+
import { n as requireAuth } from "./provider-CgDAlg6K.js";
|
|
4
|
+
import { t as HttpService } from "./http-service-DDNCO1s4.js";
|
|
5
|
+
import { t as base64ToBytes } from "./bytes-BxpimpQx.js";
|
|
6
|
+
import { isPlainObject, isString } from "es-toolkit";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
//#region src/vendors/imessage/contracts.ts
|
|
9
|
+
/**
|
|
10
|
+
* Host auth for the hosted photon-rest-proxy (REST → Spectrum gRPC).
|
|
11
|
+
* Credentials are forwarded per request; the proxy stores nothing.
|
|
12
|
+
*
|
|
13
|
+
* Proxy route map (package client → HTTP):
|
|
14
|
+
* - sendText → POST /v1/send
|
|
15
|
+
* - editText → POST /v1/edit
|
|
16
|
+
* - sendChatAction / stopTyping → POST /v1/typing
|
|
17
|
+
* - setReaction → POST /v1/react
|
|
18
|
+
* - clearReaction → POST /v1/clear-reaction (target message_id + emoji; proxy gap if not yet supported)
|
|
19
|
+
* - unsend → POST /v1/unsend
|
|
20
|
+
* - read → POST /v1/read
|
|
21
|
+
* - sendMedia → POST /v1/media
|
|
22
|
+
* - downloadFile → POST /v1/download (chat_id optional; proxy gap if still required)
|
|
23
|
+
* - ensureChat → POST /v1/ensure-chat (host-only; proxy gap until implemented)
|
|
24
|
+
*/
|
|
25
|
+
const imessageAuthSchema = z.object({
|
|
26
|
+
base_url: z.url().describe("Origin of the hosted photon-rest-proxy, for example https://photon-proxy.example.com"),
|
|
27
|
+
project_id: z.string().min(1).describe("Spectrum project id (sent as x-spectrum-project-id)"),
|
|
28
|
+
project_secret: z.string().min(1).describe("Spectrum project secret (sent as x-spectrum-project-secret)"),
|
|
29
|
+
phone: z.string().min(1).optional().describe("Optional default iMessage line phone when the project has multiple lines")
|
|
30
|
+
});
|
|
31
|
+
const imessageChatActionSchema = z.enum([
|
|
32
|
+
"typing",
|
|
33
|
+
"upload_photo",
|
|
34
|
+
"record_video",
|
|
35
|
+
"upload_video",
|
|
36
|
+
"record_voice",
|
|
37
|
+
"upload_voice",
|
|
38
|
+
"upload_document",
|
|
39
|
+
"choose_sticker",
|
|
40
|
+
"find_location",
|
|
41
|
+
"record_video_note",
|
|
42
|
+
"upload_video_note"
|
|
43
|
+
]);
|
|
44
|
+
const imessageSendTextInputSchema = z.object({
|
|
45
|
+
chat_id: z.string().min(1).describe("iMessage chat guid (e.g. any;-;alice@example.com)"),
|
|
46
|
+
text: z.string().min(1).describe("Message text"),
|
|
47
|
+
phone: z.string().min(1).optional().describe("Optional line phone override for multi-line projects")
|
|
48
|
+
});
|
|
49
|
+
const imessageMessageOutputSchema = z.object({
|
|
50
|
+
message_id: z.string().min(1).describe("Message guid (provider id for journaling)"),
|
|
51
|
+
space_id: z.string().describe("Chat guid (same as chat_id)")
|
|
52
|
+
});
|
|
53
|
+
const imessageEditTextInputSchema = z.object({
|
|
54
|
+
chat_id: z.string().min(1).describe("iMessage chat guid"),
|
|
55
|
+
message_id: z.string().min(1).describe("Message guid to edit"),
|
|
56
|
+
text: z.string().min(1).describe("Replacement text"),
|
|
57
|
+
phone: z.string().min(1).optional().describe("Optional line phone override")
|
|
58
|
+
});
|
|
59
|
+
const imessageSendChatActionInputSchema = z.object({
|
|
60
|
+
chat_id: z.string().min(1).describe("iMessage chat guid"),
|
|
61
|
+
action: imessageChatActionSchema.describe("Chat action; non-typing values map to typing start"),
|
|
62
|
+
phone: z.string().min(1).optional().describe("Optional line phone override")
|
|
63
|
+
});
|
|
64
|
+
const imessageSetReactionInputSchema = z.object({
|
|
65
|
+
chat_id: z.string().min(1).describe("iMessage chat guid"),
|
|
66
|
+
message_id: z.string().min(1).describe("Message guid to react to"),
|
|
67
|
+
emoji: z.string().min(1).max(64).describe("Tapback name (love, like, dislike, laugh, emphasize, question) or an emoji character the channel accepts"),
|
|
68
|
+
phone: z.string().min(1).optional().describe("Optional line phone override")
|
|
69
|
+
});
|
|
70
|
+
const imessageUnsendInputSchema = z.object({
|
|
71
|
+
chat_id: z.string().min(1).describe("iMessage chat guid"),
|
|
72
|
+
message_id: z.string().min(1).describe("Message guid to unsend"),
|
|
73
|
+
phone: z.string().min(1).optional().describe("Optional line phone override")
|
|
74
|
+
});
|
|
75
|
+
const imessageReadInputSchema = z.object({
|
|
76
|
+
chat_id: z.string().min(1).describe("iMessage chat guid"),
|
|
77
|
+
message_id: z.string().min(1).optional().describe("Optional; mark-read may apply to the whole chat (field kept for seam parity)"),
|
|
78
|
+
phone: z.string().min(1).optional().describe("Optional line phone override")
|
|
79
|
+
});
|
|
80
|
+
const imessageOkOutputSchema = z.object({
|
|
81
|
+
ok: z.boolean(),
|
|
82
|
+
space_id: z.string().optional()
|
|
83
|
+
});
|
|
84
|
+
const MAX_MEDIA_BYTES = 20 * 1024 * 1024;
|
|
85
|
+
/**
|
|
86
|
+
* Clear a reaction. `message_id` is the **target** message that was reacted to;
|
|
87
|
+
* `emoji` must match set-reaction. Proxy should clear by target+emoji (not reaction message id).
|
|
88
|
+
*/
|
|
89
|
+
const imessageClearReactionInputSchema = z.object({
|
|
90
|
+
chat_id: z.string().min(1).describe("iMessage chat guid"),
|
|
91
|
+
message_id: z.string().min(1).describe("Target message guid that was reacted to"),
|
|
92
|
+
emoji: z.string().min(1).max(64).describe("Same tapback name or emoji used when setting the reaction"),
|
|
93
|
+
phone: z.string().min(1).optional().describe("Optional line phone override")
|
|
94
|
+
});
|
|
95
|
+
const imessageSendMediaInputSchema = z.object({
|
|
96
|
+
chat_id: z.string().min(1).describe("iMessage chat guid"),
|
|
97
|
+
kind: z.enum(["photo", "document"]).describe("Media kind (presentation)"),
|
|
98
|
+
body_base64: z.string().min(1).describe("File body as base64"),
|
|
99
|
+
file_name: z.string().min(1).describe("File name including extension"),
|
|
100
|
+
caption: z.string().optional().describe("Optional caption sent as a follow-up text message"),
|
|
101
|
+
content_type: z.string().optional().describe("Optional MIME type; inferred from file_name when omitted"),
|
|
102
|
+
phone: z.string().min(1).optional().describe("Optional line phone override")
|
|
103
|
+
});
|
|
104
|
+
const imessageDownloadFileInputSchema = z.object({
|
|
105
|
+
file_id: z.string().min(1).describe("Attachment guid (from inbound payload or upload)"),
|
|
106
|
+
file_name: z.string().min(1).optional().describe("Preferred file name for the download result"),
|
|
107
|
+
chat_id: z.string().min(1).optional().describe("Chat guid (optional when proxy can resolve by file_id alone)"),
|
|
108
|
+
phone: z.string().min(1).optional().describe("Optional line phone override")
|
|
109
|
+
});
|
|
110
|
+
const imessageDownloadFileOutputSchema = z.object({
|
|
111
|
+
file_name: z.string(),
|
|
112
|
+
file_size: z.number().optional(),
|
|
113
|
+
body_base64: z.string().describe("Downloaded file body as base64")
|
|
114
|
+
});
|
|
115
|
+
/**
|
|
116
|
+
* Create (or resolve) a chat via proxy POST /v1/ensure-chat (host-only).
|
|
117
|
+
* One address = 1:1; two or more = group.
|
|
118
|
+
*/
|
|
119
|
+
const imessageEnsureChatInputSchema = z.object({
|
|
120
|
+
addresses: z.array(z.string().min(1)).min(1).describe("Peer phone number(s) or email(s). One address creates a 1:1 chat; two or more create a group"),
|
|
121
|
+
message: z.string().min(1).optional().describe("Optional opening text sent in the same create call"),
|
|
122
|
+
client_message_id: z.string().min(1).optional().describe("Optional idempotency key for chat creation and the optional opening send"),
|
|
123
|
+
phone: z.string().min(1).optional().describe("Optional line phone override")
|
|
124
|
+
});
|
|
125
|
+
const imessageEnsureChatOutputSchema = z.object({
|
|
126
|
+
chat_id: z.string().min(1).describe("Chat guid for later send, edit, react, or unsend"),
|
|
127
|
+
message_id: z.string().min(1).optional().describe("Guid of the opening message when message was provided and the server returned one")
|
|
128
|
+
});
|
|
129
|
+
//#endregion
|
|
130
|
+
//#region src/vendors/imessage/domain.ts
|
|
131
|
+
/**
|
|
132
|
+
* photon-rest-proxy response parse + failure helpers (no HTTP).
|
|
133
|
+
*/
|
|
134
|
+
var ImessageClientError = class extends ToolError {
|
|
135
|
+
failureKind;
|
|
136
|
+
constructor(input) {
|
|
137
|
+
super(input.message, {
|
|
138
|
+
code: mapStatusToToolCode(input.status, input.code),
|
|
139
|
+
retryable: input.failureKind === "outcome_unknown",
|
|
140
|
+
cause: input.cause,
|
|
141
|
+
details: {
|
|
142
|
+
failure_kind: input.failureKind,
|
|
143
|
+
status: input.status,
|
|
144
|
+
proxy_error: input.code
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
this.name = "ImessageClientError";
|
|
148
|
+
this.failureKind = input.failureKind;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
function isImessageDefiniteRejection(error) {
|
|
152
|
+
return error instanceof ImessageClientError && error.failureKind === "definite_rejection";
|
|
153
|
+
}
|
|
154
|
+
function isImessageOutcomeUnknown(error) {
|
|
155
|
+
return error instanceof ImessageClientError && error.failureKind === "outcome_unknown";
|
|
156
|
+
}
|
|
157
|
+
function mapStatusToToolCode(status, proxyCode) {
|
|
158
|
+
if (status === 401) return "bad_auth";
|
|
159
|
+
if (status === 403) return "forbidden";
|
|
160
|
+
if (status === 404) return "not_found";
|
|
161
|
+
if (status === 400) return "bad_input";
|
|
162
|
+
if (status === 429) return "rate_limited";
|
|
163
|
+
if (proxyCode === "unauthorized") return "bad_auth";
|
|
164
|
+
if (proxyCode === "message_not_found" || proxyCode === "not_found") return "not_found";
|
|
165
|
+
if (proxyCode === "unsupported" || proxyCode === "not_implemented") return "unsupported";
|
|
166
|
+
return "upstream";
|
|
167
|
+
}
|
|
168
|
+
function isDefiniteStatus(status) {
|
|
169
|
+
return status === 400 || status === 401 || status === 403 || status === 404;
|
|
170
|
+
}
|
|
171
|
+
/** Parse photon-rest-proxy JSON error body or throw on non-2xx. */
|
|
172
|
+
function assertProxyOk(label, status, data) {
|
|
173
|
+
if (status >= 200 && status < 300) return;
|
|
174
|
+
let message = `${label} failed with HTTP ${status}`;
|
|
175
|
+
let code;
|
|
176
|
+
if (isPlainObject(data)) {
|
|
177
|
+
const err = data["error"];
|
|
178
|
+
const detail = data["detail"];
|
|
179
|
+
if (isString(err) && err.length > 0) {
|
|
180
|
+
code = err;
|
|
181
|
+
message = isString(detail) && detail.length > 0 ? `${err}: ${detail}` : err;
|
|
182
|
+
} else if (isString(detail) && detail.length > 0) message = detail;
|
|
183
|
+
}
|
|
184
|
+
throw new ImessageClientError({
|
|
185
|
+
message,
|
|
186
|
+
failureKind: isDefiniteStatus(status) ? "definite_rejection" : "outcome_unknown",
|
|
187
|
+
status,
|
|
188
|
+
...code && { code }
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
function requireString(data, key, label) {
|
|
192
|
+
const value = data[key];
|
|
193
|
+
if (!isString(value) || value.length === 0) throw new ToolError(`iMessage proxy ${label} missing ${key}`, { code: "upstream" });
|
|
194
|
+
return value;
|
|
195
|
+
}
|
|
196
|
+
/** Prefer space_id; accept chat_id alias from newer proxy shapes. */
|
|
197
|
+
function spaceOrChatId(data, label) {
|
|
198
|
+
const spaceId = data["space_id"];
|
|
199
|
+
if (isString(spaceId) && spaceId.length > 0) return spaceId;
|
|
200
|
+
const chatId = data["chat_id"];
|
|
201
|
+
if (isString(chatId) && chatId.length > 0) return chatId;
|
|
202
|
+
throw new ToolError(`iMessage proxy ${label} missing space_id`, { code: "upstream" });
|
|
203
|
+
}
|
|
204
|
+
function parseMessageResult(data, label = "send") {
|
|
205
|
+
if (!isPlainObject(data) || data["ok"] !== true) throw new ToolError(`iMessage proxy returned an unexpected ${label} payload`, { code: "upstream" });
|
|
206
|
+
return {
|
|
207
|
+
space_id: spaceOrChatId(data, label),
|
|
208
|
+
message_id: requireString(data, "message_id", label)
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function parseOkResult(data) {
|
|
212
|
+
if (!isPlainObject(data) || data["ok"] !== true) throw new ToolError("iMessage proxy returned an unexpected ok payload", { code: "upstream" });
|
|
213
|
+
const spaceId = data["space_id"];
|
|
214
|
+
const chatId = data["chat_id"];
|
|
215
|
+
const id = isString(spaceId) && spaceId.length > 0 ? spaceId : isString(chatId) && chatId.length > 0 ? chatId : void 0;
|
|
216
|
+
return {
|
|
217
|
+
ok: true,
|
|
218
|
+
...id && { space_id: id }
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function parseEnsureChatResult(data) {
|
|
222
|
+
if (!isPlainObject(data) || data["ok"] !== true) throw new ToolError("iMessage proxy returned an unexpected ensure-chat payload", { code: "upstream" });
|
|
223
|
+
const chatId = spaceOrChatId(data, "ensure-chat");
|
|
224
|
+
const messageId = data["message_id"];
|
|
225
|
+
return {
|
|
226
|
+
chat_id: chatId,
|
|
227
|
+
...isString(messageId) && messageId.length > 0 && { message_id: messageId }
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
/** Map messaging-style chat_id to proxy space_id body fields. */
|
|
231
|
+
function spaceBody(chatId, phone, extra = {}) {
|
|
232
|
+
return {
|
|
233
|
+
platform: "imessage",
|
|
234
|
+
...extra,
|
|
235
|
+
...chatId && { space_id: chatId },
|
|
236
|
+
...phone && { phone }
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
/** Decode and size-check media base64 for sendMedia. */
|
|
240
|
+
function decodeMediaBody(bodyBase64) {
|
|
241
|
+
let bytes;
|
|
242
|
+
try {
|
|
243
|
+
bytes = base64ToBytes(bodyBase64);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
throw new ToolError("Invalid base64 body", {
|
|
246
|
+
code: "bad_input",
|
|
247
|
+
cause: error
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
if (bytes.byteLength === 0) throw new ToolError("Media body must not be empty", { code: "bad_input" });
|
|
251
|
+
if (bytes.byteLength > 20971520) throw new ToolError("Media exceeds 20 MiB limit", {
|
|
252
|
+
code: "too_large",
|
|
253
|
+
details: {
|
|
254
|
+
max_bytes: MAX_MEDIA_BYTES,
|
|
255
|
+
content_length: bytes.byteLength
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
/** Build POST /v1/media JSON body (base64 already validated). */
|
|
260
|
+
function mediaBody(input, phone) {
|
|
261
|
+
decodeMediaBody(input.body_base64);
|
|
262
|
+
return spaceBody(input.chat_id, phone, {
|
|
263
|
+
body_base64: input.body_base64,
|
|
264
|
+
file_name: input.file_name,
|
|
265
|
+
...input.content_type && { mime_type: input.content_type },
|
|
266
|
+
...input.caption && { caption: input.caption }
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
function parseDownloadResult(input, data) {
|
|
270
|
+
if (!isPlainObject(data) || data["ok"] !== true) throw new ToolError("iMessage proxy returned an unexpected download payload", { code: "upstream" });
|
|
271
|
+
const bodyBase64 = data["body_base64"];
|
|
272
|
+
if (!isString(bodyBase64) || bodyBase64.length === 0) throw new ToolError("iMessage proxy download missing body_base64", { code: "upstream" });
|
|
273
|
+
const name = data["file_name"];
|
|
274
|
+
const size = data["file_size"];
|
|
275
|
+
return {
|
|
276
|
+
file_name: input.file_name ?? (isString(name) && name.length > 0 ? name : input.file_id),
|
|
277
|
+
...typeof size === "number" && Number.isFinite(size) && { file_size: size },
|
|
278
|
+
body_base64: bodyBase64
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
//#endregion
|
|
282
|
+
//#region src/vendors/imessage/client.ts
|
|
283
|
+
/**
|
|
284
|
+
* iMessage vendor client via hosted photon-rest-proxy (REST → Spectrum gRPC).
|
|
285
|
+
* Host: `new ImessageClient(auth)`. Agent tools: `fromContext(ctx)`.
|
|
286
|
+
*
|
|
287
|
+
* Workers-safe: only HTTP to the proxy. No Photon SDK / gRPC in this package.
|
|
288
|
+
*/
|
|
289
|
+
var ImessageClient = class ImessageClient {
|
|
290
|
+
#http;
|
|
291
|
+
#defaultPhone;
|
|
292
|
+
constructor(auth, options = {}) {
|
|
293
|
+
const parsed = imessageAuthSchema.safeParse(auth);
|
|
294
|
+
if (!parsed.success) throw new ToolError("Invalid iMessage auth credentials", {
|
|
295
|
+
code: "bad_auth",
|
|
296
|
+
details: { issues: parsed.error.issues.map((issue) => issue.message) }
|
|
297
|
+
});
|
|
298
|
+
const { base_url, project_id, project_secret, phone } = parsed.data;
|
|
299
|
+
this.#defaultPhone = phone;
|
|
300
|
+
this.#http = new HttpService({
|
|
301
|
+
...options,
|
|
302
|
+
baseURL: base_url,
|
|
303
|
+
headers: {
|
|
304
|
+
"Content-Type": "application/json",
|
|
305
|
+
"x-spectrum-project-id": project_id,
|
|
306
|
+
"x-spectrum-project-secret": project_secret
|
|
307
|
+
},
|
|
308
|
+
label: "iMessage"
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
static fromContext(ctx) {
|
|
312
|
+
const auth = requireAuth(ctx, imessageAuthSchema);
|
|
313
|
+
return new ImessageClient(auth, {
|
|
314
|
+
...ctx.fetch && { fetch: ctx.fetch },
|
|
315
|
+
...ctx.signal && { signal: ctx.signal }
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
#phone(override) {
|
|
319
|
+
return override ?? this.#defaultPhone;
|
|
320
|
+
}
|
|
321
|
+
async #post(path, body, label) {
|
|
322
|
+
const res = await this.#http.post(path, body, {
|
|
323
|
+
label,
|
|
324
|
+
noThrow: true
|
|
325
|
+
});
|
|
326
|
+
assertProxyOk(label, res.status, res.data);
|
|
327
|
+
return res.data;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Create a chat (1:1 or group). Host-only; not an agent tool.
|
|
331
|
+
* Proxy: POST /v1/ensure-chat (fill on proxy if not yet shipped).
|
|
332
|
+
*/
|
|
333
|
+
async ensureChat(input) {
|
|
334
|
+
return parseEnsureChatResult(await this.#post("/v1/ensure-chat", spaceBody(void 0, this.#phone(input.phone), {
|
|
335
|
+
addresses: input.addresses,
|
|
336
|
+
...input.message && { message: input.message },
|
|
337
|
+
...input.client_message_id && { client_message_id: input.client_message_id }
|
|
338
|
+
}), "iMessage ensureChat"));
|
|
339
|
+
}
|
|
340
|
+
/** POST /v1/send */
|
|
341
|
+
async sendText(input) {
|
|
342
|
+
return parseMessageResult(await this.#post("/v1/send", spaceBody(input.chat_id, this.#phone(input.phone), { text: input.text }), "iMessage send"), "send");
|
|
343
|
+
}
|
|
344
|
+
/** POST /v1/edit */
|
|
345
|
+
async editText(input) {
|
|
346
|
+
const data = await this.#post("/v1/edit", spaceBody(input.chat_id, this.#phone(input.phone), {
|
|
347
|
+
message_id: input.message_id,
|
|
348
|
+
text: input.text
|
|
349
|
+
}), "iMessage edit");
|
|
350
|
+
if (isPlainObject(data) && data["ok"] === true && isString(data["message_id"]) && data["message_id"].length > 0) return parseMessageResult(data, "edit");
|
|
351
|
+
return {
|
|
352
|
+
space_id: parseOkResult(data).space_id ?? input.chat_id,
|
|
353
|
+
message_id: input.message_id
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* POST /v1/typing.
|
|
358
|
+
* Non-typing chat actions map to typing start (presentation parity with other channels).
|
|
359
|
+
*/
|
|
360
|
+
async sendChatAction(input) {
|
|
361
|
+
await this.#post("/v1/typing", spaceBody(input.chat_id, this.#phone(input.phone), { action: "start" }), "iMessage typing");
|
|
362
|
+
}
|
|
363
|
+
/** Stop typing indicator. */
|
|
364
|
+
async stopTyping(input) {
|
|
365
|
+
await this.#post("/v1/typing", spaceBody(input.chat_id, this.#phone(input.phone), { action: "stop" }), "iMessage typing stop");
|
|
366
|
+
}
|
|
367
|
+
/** POST /v1/react — returns reaction/message guid for journaling. */
|
|
368
|
+
async setReaction(input) {
|
|
369
|
+
return parseMessageResult(await this.#post("/v1/react", spaceBody(input.chat_id, this.#phone(input.phone), {
|
|
370
|
+
message_id: input.message_id,
|
|
371
|
+
emoji: input.emoji
|
|
372
|
+
}), "iMessage react"), "react");
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* POST /v1/clear-reaction.
|
|
376
|
+
* Package contract: target message_id + emoji (same as setReaction).
|
|
377
|
+
* Proxy should clear by target+emoji; older proxies that only accept reaction message ids need a gap fill.
|
|
378
|
+
*/
|
|
379
|
+
async clearReaction(input) {
|
|
380
|
+
await this.#post("/v1/clear-reaction", spaceBody(input.chat_id, this.#phone(input.phone), {
|
|
381
|
+
message_id: input.message_id,
|
|
382
|
+
emoji: input.emoji
|
|
383
|
+
}), "iMessage clearReaction");
|
|
384
|
+
}
|
|
385
|
+
/** POST /v1/unsend */
|
|
386
|
+
async unsend(input) {
|
|
387
|
+
await this.#post("/v1/unsend", spaceBody(input.chat_id, this.#phone(input.phone), { message_id: input.message_id }), "iMessage unsend");
|
|
388
|
+
}
|
|
389
|
+
/** POST /v1/read */
|
|
390
|
+
async read(input) {
|
|
391
|
+
await this.#post("/v1/read", spaceBody(input.chat_id, this.#phone(input.phone), { ...input.message_id && { message_id: input.message_id } }), "iMessage read");
|
|
392
|
+
}
|
|
393
|
+
/** POST /v1/media */
|
|
394
|
+
async sendMedia(input) {
|
|
395
|
+
return parseMessageResult(await this.#post("/v1/media", mediaBody(input, this.#phone(input.phone)), "iMessage sendMedia"), "media");
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* POST /v1/download.
|
|
399
|
+
* Prefer attachment guid alone; pass chat_id when the proxy still requires a space.
|
|
400
|
+
*/
|
|
401
|
+
async downloadFile(input) {
|
|
402
|
+
return parseDownloadResult(input, await this.#post("/v1/download", spaceBody(input.chat_id, this.#phone(input.phone), { file_id: input.file_id }), "iMessage downloadFile"));
|
|
403
|
+
}
|
|
404
|
+
async answerCallback(_input) {}
|
|
405
|
+
};
|
|
406
|
+
//#endregion
|
|
407
|
+
//#region src/vendors/imessage/module.ts
|
|
408
|
+
const imessageSendTextTool = defineTool({
|
|
409
|
+
id: "imessage-send-text",
|
|
410
|
+
name: "imessageSendText",
|
|
411
|
+
description: "Send a text message to an iMessage chat. chat_id is the chat guid (e.g. any;-;+1555…). Returns message_id (guid) for later edits, reactions, or unsend.",
|
|
412
|
+
inputSchema: imessageSendTextInputSchema,
|
|
413
|
+
outputSchema: imessageMessageOutputSchema,
|
|
414
|
+
sideEffect: "send",
|
|
415
|
+
runtime: "both",
|
|
416
|
+
network: true,
|
|
417
|
+
execute: async (input, ctx) => ImessageClient.fromContext(ctx).sendText(input)
|
|
418
|
+
});
|
|
419
|
+
const imessageEditTextTool = defineTool({
|
|
420
|
+
id: "imessage-edit-text",
|
|
421
|
+
name: "imessageEditText",
|
|
422
|
+
description: "Edit the text of a previously sent iMessage. Requires chat guid and message guid.",
|
|
423
|
+
inputSchema: imessageEditTextInputSchema,
|
|
424
|
+
outputSchema: imessageMessageOutputSchema,
|
|
425
|
+
sideEffect: "write",
|
|
426
|
+
runtime: "both",
|
|
427
|
+
network: true,
|
|
428
|
+
execute: async (input, ctx) => ImessageClient.fromContext(ctx).editText(input)
|
|
429
|
+
});
|
|
430
|
+
const imessageSendChatActionTool = defineTool({
|
|
431
|
+
id: "imessage-send-chat-action",
|
|
432
|
+
name: "imessageSendChatAction",
|
|
433
|
+
description: "Show a typing indicator in an iMessage chat while a response is being prepared.",
|
|
434
|
+
inputSchema: imessageSendChatActionInputSchema,
|
|
435
|
+
outputSchema: imessageOkOutputSchema,
|
|
436
|
+
sideEffect: "none",
|
|
437
|
+
runtime: "both",
|
|
438
|
+
network: true,
|
|
439
|
+
execute: async (input, ctx) => {
|
|
440
|
+
await ImessageClient.fromContext(ctx).sendChatAction(input);
|
|
441
|
+
return {
|
|
442
|
+
ok: true,
|
|
443
|
+
space_id: input.chat_id
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
const imessageSetReactionTool = defineTool({
|
|
448
|
+
id: "imessage-set-reaction",
|
|
449
|
+
name: "imessageSetReaction",
|
|
450
|
+
description: "React to an iMessage with a tapback (love, like, dislike, laugh, emphasize, question) or free emoji. Returns a message guid for journaling. To clear, call clear-reaction with the same target message_id and emoji.",
|
|
451
|
+
inputSchema: imessageSetReactionInputSchema,
|
|
452
|
+
outputSchema: imessageMessageOutputSchema,
|
|
453
|
+
sideEffect: "write",
|
|
454
|
+
runtime: "both",
|
|
455
|
+
network: true,
|
|
456
|
+
execute: async (input, ctx) => ImessageClient.fromContext(ctx).setReaction(input)
|
|
457
|
+
});
|
|
458
|
+
const imessageClearReactionTool = defineTool({
|
|
459
|
+
id: "imessage-clear-reaction",
|
|
460
|
+
name: "imessageClearReaction",
|
|
461
|
+
description: "Clear an iMessage reaction. message_id is the target message that was reacted to; emoji must match set-reaction (tapback name or emoji character).",
|
|
462
|
+
inputSchema: imessageClearReactionInputSchema,
|
|
463
|
+
outputSchema: imessageOkOutputSchema,
|
|
464
|
+
sideEffect: "delete",
|
|
465
|
+
runtime: "both",
|
|
466
|
+
network: true,
|
|
467
|
+
execute: async (input, ctx) => {
|
|
468
|
+
await ImessageClient.fromContext(ctx).clearReaction(input);
|
|
469
|
+
return {
|
|
470
|
+
ok: true,
|
|
471
|
+
space_id: input.chat_id
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
const imessageUnsendTool = defineTool({
|
|
476
|
+
id: "imessage-unsend",
|
|
477
|
+
name: "imessageUnsend",
|
|
478
|
+
description: "Unsend a previously sent iMessage using its chat guid and message guid.",
|
|
479
|
+
inputSchema: imessageUnsendInputSchema,
|
|
480
|
+
outputSchema: imessageOkOutputSchema,
|
|
481
|
+
sideEffect: "delete",
|
|
482
|
+
runtime: "both",
|
|
483
|
+
network: true,
|
|
484
|
+
execute: async (input, ctx) => {
|
|
485
|
+
await ImessageClient.fromContext(ctx).unsend(input);
|
|
486
|
+
return {
|
|
487
|
+
ok: true,
|
|
488
|
+
space_id: input.chat_id
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
const imessageReadTool = defineTool({
|
|
493
|
+
id: "imessage-read",
|
|
494
|
+
name: "imessageRead",
|
|
495
|
+
description: "Mark an iMessage conversation as read (whole chat).",
|
|
496
|
+
inputSchema: imessageReadInputSchema,
|
|
497
|
+
outputSchema: imessageOkOutputSchema,
|
|
498
|
+
sideEffect: "write",
|
|
499
|
+
runtime: "both",
|
|
500
|
+
network: true,
|
|
501
|
+
execute: async (input, ctx) => {
|
|
502
|
+
await ImessageClient.fromContext(ctx).read(input);
|
|
503
|
+
return {
|
|
504
|
+
ok: true,
|
|
505
|
+
space_id: input.chat_id
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
const imessageSendMediaTool = defineTool({
|
|
510
|
+
id: "imessage-send-media",
|
|
511
|
+
name: "imessageSendMedia",
|
|
512
|
+
description: "Upload and send one photo or document to an iMessage chat from base64 bytes. Optional caption is sent as a follow-up text message.",
|
|
513
|
+
inputSchema: imessageSendMediaInputSchema,
|
|
514
|
+
outputSchema: imessageMessageOutputSchema,
|
|
515
|
+
sideEffect: "send",
|
|
516
|
+
runtime: "both",
|
|
517
|
+
network: true,
|
|
518
|
+
execute: async (input, ctx) => ImessageClient.fromContext(ctx).sendMedia(input)
|
|
519
|
+
});
|
|
520
|
+
const imessageDownloadFileTool = defineTool({
|
|
521
|
+
id: "imessage-download-file",
|
|
522
|
+
name: "imessageDownloadFile",
|
|
523
|
+
description: "Download attachment bytes by attachment guid (file_id from inbound or upload).",
|
|
524
|
+
inputSchema: imessageDownloadFileInputSchema,
|
|
525
|
+
outputSchema: imessageDownloadFileOutputSchema,
|
|
526
|
+
sideEffect: "none",
|
|
527
|
+
runtime: "both",
|
|
528
|
+
network: true,
|
|
529
|
+
execute: async (input, ctx) => ImessageClient.fromContext(ctx).downloadFile(input)
|
|
530
|
+
});
|
|
531
|
+
const imessageModule = defineModule({
|
|
532
|
+
id: "imessage",
|
|
533
|
+
title: "iMessage",
|
|
534
|
+
description: "iMessage tools for sending and editing text or media, typing indicators, reactions, unsend, read state, and attachment download via a bound photon-rest-proxy.",
|
|
535
|
+
runtime: "both",
|
|
536
|
+
auth: {
|
|
537
|
+
type: "custom",
|
|
538
|
+
schema: imessageAuthSchema
|
|
539
|
+
},
|
|
540
|
+
categories: ["messaging", "chat"],
|
|
541
|
+
classification: "pii",
|
|
542
|
+
tags: ["imessage", "photon"],
|
|
543
|
+
tools: [
|
|
544
|
+
imessageSendTextTool,
|
|
545
|
+
imessageEditTextTool,
|
|
546
|
+
imessageSendChatActionTool,
|
|
547
|
+
imessageSetReactionTool,
|
|
548
|
+
imessageClearReactionTool,
|
|
549
|
+
imessageUnsendTool,
|
|
550
|
+
imessageReadTool,
|
|
551
|
+
imessageSendMediaTool,
|
|
552
|
+
imessageDownloadFileTool
|
|
553
|
+
]
|
|
554
|
+
});
|
|
555
|
+
//#endregion
|
|
556
|
+
export { imessageUnsendInputSchema as A, imessageMessageOutputSchema as C, imessageSendMediaInputSchema as D, imessageSendChatActionInputSchema as E, imessageSendTextInputSchema as O, imessageEnsureChatOutputSchema as S, imessageReadInputSchema as T, imessageClearReactionInputSchema as _, imessageReadTool as a, imessageEditTextInputSchema as b, imessageSendTextTool as c, ImessageClient as d, ImessageClientError as f, imessageAuthSchema as g, MAX_MEDIA_BYTES as h, imessageModule as i, imessageSetReactionInputSchema as k, imessageSetReactionTool as l, isImessageOutcomeUnknown as m, imessageDownloadFileTool as n, imessageSendChatActionTool as o, isImessageDefiniteRejection as p, imessageEditTextTool as r, imessageSendMediaTool as s, imessageClearReactionTool as t, imessageUnsendTool as u, imessageDownloadFileInputSchema as v, imessageOkOutputSchema as w, imessageEnsureChatInputSchema as x, imessageDownloadFileOutputSchema as y };
|
|
557
|
+
|
|
558
|
+
//# sourceMappingURL=imessage-CH49-sFn.js.map
|