@carrierllc/mcp 0.1.0 → 0.2.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/dist/apps/app-state.d.ts +19 -0
- package/dist/apps/app-state.d.ts.map +1 -0
- package/dist/apps/app-state.js +28 -0
- package/dist/apps/app-state.js.map +1 -0
- package/dist/apps/balance-topup.d.ts +19 -0
- package/dist/apps/balance-topup.d.ts.map +1 -0
- package/dist/apps/balance-topup.js +121 -0
- package/dist/apps/balance-topup.js.map +1 -0
- package/dist/apps/fleet-health-app.d.ts +29 -0
- package/dist/apps/fleet-health-app.d.ts.map +1 -0
- package/dist/apps/fleet-health-app.js +152 -0
- package/dist/apps/fleet-health-app.js.map +1 -0
- package/dist/apps/index.d.ts +37 -0
- package/dist/apps/index.d.ts.map +1 -0
- package/dist/apps/index.js +42 -0
- package/dist/apps/index.js.map +1 -0
- package/dist/apps/provisioning-wizard.d.ts +11 -0
- package/dist/apps/provisioning-wizard.d.ts.map +1 -0
- package/dist/apps/provisioning-wizard.js +345 -0
- package/dist/apps/provisioning-wizard.js.map +1 -0
- package/dist/audit.d.ts +31 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +42 -0
- package/dist/audit.js.map +1 -0
- package/dist/billing-thresholds.d.ts +71 -0
- package/dist/billing-thresholds.d.ts.map +1 -0
- package/dist/billing-thresholds.js +238 -0
- package/dist/billing-thresholds.js.map +1 -0
- package/dist/billing.d.ts +95 -0
- package/dist/billing.d.ts.map +1 -0
- package/dist/billing.js +239 -0
- package/dist/billing.js.map +1 -0
- package/dist/clerk.d.ts +125 -0
- package/dist/clerk.d.ts.map +1 -0
- package/dist/clerk.js +389 -0
- package/dist/clerk.js.map +1 -0
- package/dist/client.d.ts +12 -15
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +48 -55
- package/dist/client.js.map +1 -1
- package/dist/credits.d.ts +165 -0
- package/dist/credits.d.ts.map +1 -0
- package/dist/credits.js +483 -0
- package/dist/credits.js.map +1 -0
- package/dist/index.d.ts +6 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +74 -23
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +2 -8
- package/dist/intelligence.d.ts.map +1 -1
- package/dist/intelligence.js +321 -154
- package/dist/intelligence.js.map +1 -1
- package/dist/list-recent-ocs-events.d.ts +48 -0
- package/dist/list-recent-ocs-events.d.ts.map +1 -0
- package/dist/list-recent-ocs-events.js +160 -0
- package/dist/list-recent-ocs-events.js.map +1 -0
- package/dist/manus-client.d.ts +429 -0
- package/dist/manus-client.d.ts.map +1 -0
- package/dist/manus-client.js +401 -0
- package/dist/manus-client.js.map +1 -0
- package/dist/manus-common.d.ts +5 -0
- package/dist/manus-common.d.ts.map +1 -0
- package/dist/manus-common.js +5 -0
- package/dist/manus-common.js.map +1 -0
- package/dist/manus-schedule.d.ts +74 -0
- package/dist/manus-schedule.d.ts.map +1 -0
- package/dist/manus-schedule.js +213 -0
- package/dist/manus-schedule.js.map +1 -0
- package/dist/manus-usage.d.ts +32 -0
- package/dist/manus-usage.d.ts.map +1 -0
- package/dist/manus-usage.js +120 -0
- package/dist/manus-usage.js.map +1 -0
- package/dist/manus-webhook.d.ts +60 -0
- package/dist/manus-webhook.d.ts.map +1 -0
- package/dist/manus-webhook.js +361 -0
- package/dist/manus-webhook.js.map +1 -0
- package/dist/pricing-tools.d.ts +26 -0
- package/dist/pricing-tools.d.ts.map +1 -0
- package/dist/pricing-tools.js +428 -0
- package/dist/pricing-tools.js.map +1 -0
- package/dist/projects-tools.d.ts +39 -0
- package/dist/projects-tools.d.ts.map +1 -0
- package/dist/projects-tools.js +545 -0
- package/dist/projects-tools.js.map +1 -0
- package/dist/prompts.d.ts +1 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +1 -0
- package/dist/prompts.js.map +1 -1
- package/dist/stripe-connect-tools.d.ts +33 -0
- package/dist/stripe-connect-tools.d.ts.map +1 -0
- package/dist/stripe-connect-tools.js +504 -0
- package/dist/stripe-connect-tools.js.map +1 -0
- package/dist/timing-safe-equal.d.ts +5 -0
- package/dist/timing-safe-equal.d.ts.map +1 -0
- package/dist/timing-safe-equal.js +13 -0
- package/dist/timing-safe-equal.js.map +1 -0
- package/dist/tools-backlog.d.ts +28 -0
- package/dist/tools-backlog.d.ts.map +1 -0
- package/dist/tools-backlog.js +315 -0
- package/dist/tools-backlog.js.map +1 -0
- package/dist/tools-carrier-ask.d.ts +138 -0
- package/dist/tools-carrier-ask.d.ts.map +1 -0
- package/dist/tools-carrier-ask.js +913 -0
- package/dist/tools-carrier-ask.js.map +1 -0
- package/dist/tools-pricing.d.ts +18 -0
- package/dist/tools-pricing.d.ts.map +1 -0
- package/dist/tools-pricing.js +172 -0
- package/dist/tools-pricing.js.map +1 -0
- package/dist/tools-ui-agent-ask.d.ts +29 -0
- package/dist/tools-ui-agent-ask.d.ts.map +1 -0
- package/dist/tools-ui-agent-ask.js +272 -0
- package/dist/tools-ui-agent-ask.js.map +1 -0
- package/dist/tools-ui-agent-schedule.d.ts +29 -0
- package/dist/tools-ui-agent-schedule.d.ts.map +1 -0
- package/dist/tools-ui-agent-schedule.js +517 -0
- package/dist/tools-ui-agent-schedule.js.map +1 -0
- package/dist/tools-ui-agent.d.ts +40 -0
- package/dist/tools-ui-agent.d.ts.map +1 -0
- package/dist/tools-ui-agent.js +508 -0
- package/dist/tools-ui-agent.js.map +1 -0
- package/dist/tools.d.ts +44 -13
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +794 -201
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +291 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +14 -8
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manus Schedule API v2 client.
|
|
3
|
+
*
|
|
4
|
+
* Endpoints (Manus open.manus.ai/docs/v2 dot-notation pattern):
|
|
5
|
+
* POST /v2/schedule.create — create a recurring scheduled agent run
|
|
6
|
+
* GET /v2/schedule.list — list all schedules for this API key
|
|
7
|
+
* POST /v2/schedule.delete — delete a schedule by ID
|
|
8
|
+
* POST /v2/schedule.pause — pause a schedule
|
|
9
|
+
* POST /v2/schedule.resume — resume a paused schedule
|
|
10
|
+
*
|
|
11
|
+
* Auth: `x-manus-api-key` header (same pattern as task.create).
|
|
12
|
+
*/
|
|
13
|
+
import { MANUS_API_BASE } from "./manus-common.js";
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Errors
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
export class ManusScheduleError extends Error {
|
|
18
|
+
statusCode;
|
|
19
|
+
constructor(message, statusCode) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.statusCode = statusCode;
|
|
22
|
+
this.name = "ManusScheduleError";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Cron validation
|
|
27
|
+
// Minimum interval: 5 minutes. Expands the minute field (lists, ranges,
|
|
28
|
+
// steps, */N) and rejects if any adjacent firing gap (including wrap) is < 5.
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
/**
|
|
31
|
+
* Expands the minute field into sorted unique minutes 0–59, or null if unsupported.
|
|
32
|
+
*/
|
|
33
|
+
function expandCronMinuteField(minuteField) {
|
|
34
|
+
if (minuteField === "*" || minuteField.includes(" ")) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const tokens = minuteField.split(",").map((t) => t.trim()).filter(Boolean);
|
|
38
|
+
const set = new Set();
|
|
39
|
+
for (const token of tokens) {
|
|
40
|
+
const stepWildcard = /^[*]\/(\d+)$/.exec(token);
|
|
41
|
+
if (stepWildcard) {
|
|
42
|
+
const step = parseInt(stepWildcard[1] ?? "0", 10);
|
|
43
|
+
if (step < 1)
|
|
44
|
+
return null;
|
|
45
|
+
for (let m = 0; m < 60; m += step)
|
|
46
|
+
set.add(m);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const rangeWithStep = /^(\d+)-(\d+)\/(\d+)$/.exec(token);
|
|
50
|
+
if (rangeWithStep) {
|
|
51
|
+
const start = parseInt(rangeWithStep[1] ?? "0", 10);
|
|
52
|
+
const end = parseInt(rangeWithStep[2] ?? "0", 10);
|
|
53
|
+
const step = parseInt(rangeWithStep[3] ?? "0", 10);
|
|
54
|
+
if (step < 1 || start > end)
|
|
55
|
+
return null;
|
|
56
|
+
for (let m = start; m <= end; m += step)
|
|
57
|
+
set.add(m);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const rangeOnly = /^(\d+)-(\d+)$/.exec(token);
|
|
61
|
+
if (rangeOnly) {
|
|
62
|
+
const start = parseInt(rangeOnly[1] ?? "0", 10);
|
|
63
|
+
const end = parseInt(rangeOnly[2] ?? "0", 10);
|
|
64
|
+
if (start > end)
|
|
65
|
+
return null;
|
|
66
|
+
for (let m = start; m <= end; m++)
|
|
67
|
+
set.add(m);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const single = /^(\d+)$/.exec(token);
|
|
71
|
+
if (single) {
|
|
72
|
+
set.add(parseInt(single[1] ?? "0", 10));
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const arr = Array.from(set).sort((a, b) => a - b);
|
|
78
|
+
for (const v of arr) {
|
|
79
|
+
if (v < 0 || v > 59)
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return arr;
|
|
83
|
+
}
|
|
84
|
+
function minuteFieldViolatesFiveMinuteRule(minuteField, fullCron) {
|
|
85
|
+
const minutes = expandCronMinuteField(minuteField);
|
|
86
|
+
if (minutes === null) {
|
|
87
|
+
return (`Cron expression rejected: unrecognized or unsupported minute field '${minuteField}'. ` +
|
|
88
|
+
"Minimum interval is 5 minutes; use lists, ranges with step ≥ 5, or */5 or higher.");
|
|
89
|
+
}
|
|
90
|
+
if (minutes.length === 0) {
|
|
91
|
+
return `Cron expression rejected: minute field '${minuteField}' expands to no valid minutes.`;
|
|
92
|
+
}
|
|
93
|
+
if (minutes.length === 1) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
for (let i = 1; i < minutes.length; i++) {
|
|
97
|
+
const gap = (minutes[i] ?? 0) - (minutes[i - 1] ?? 0);
|
|
98
|
+
if (gap < 5) {
|
|
99
|
+
return (`Cron expression rejected: '${fullCron}' implies a ${gap}-minute gap in the minute field. ` +
|
|
100
|
+
"Minimum allowed interval is 5 minutes.");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const wrapGap = 60 - (minutes[minutes.length - 1] ?? 0) + (minutes[0] ?? 0);
|
|
104
|
+
if (wrapGap < 5) {
|
|
105
|
+
return (`Cron expression rejected: '${fullCron}' implies a ${wrapGap}-minute wraparound gap in the minute field. ` +
|
|
106
|
+
"Minimum allowed interval is 5 minutes.");
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Returns an error string if the cron expression is invalid or too frequent,
|
|
112
|
+
* or null if it's acceptable.
|
|
113
|
+
*
|
|
114
|
+
* Rules:
|
|
115
|
+
* - Must have exactly 5 fields (standard cron, no seconds).
|
|
116
|
+
* - Minute field must not be `*` (would run every minute).
|
|
117
|
+
* - The minute field is expanded (including star/N steps, a-b ranges, a-b/c
|
|
118
|
+
* range-steps, and comma unions); every gap between consecutive runs within
|
|
119
|
+
* the hour, and the wrap gap to the next hour, must be at least 5 minutes.
|
|
120
|
+
*/
|
|
121
|
+
export function validateCron(cron) {
|
|
122
|
+
const parts = cron.trim().split(/\s+/);
|
|
123
|
+
if (parts.length !== 5) {
|
|
124
|
+
return `Invalid cron expression: expected 5 fields (minute hour day month weekday), got ${parts.length}.`;
|
|
125
|
+
}
|
|
126
|
+
const [minuteField] = parts;
|
|
127
|
+
if (minuteField === "*") {
|
|
128
|
+
return "Cron expression rejected: '* * * * *' runs every minute. Minimum allowed interval is 5 minutes.";
|
|
129
|
+
}
|
|
130
|
+
return minuteFieldViolatesFiveMinuteRule(minuteField ?? "", cron);
|
|
131
|
+
}
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// API functions
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
export async function createSchedule(apiKey, params) {
|
|
136
|
+
const body = {
|
|
137
|
+
name: params.name,
|
|
138
|
+
cron: params.cron,
|
|
139
|
+
prompt_template: params.prompt_template,
|
|
140
|
+
agent_profile: params.agent_profile ?? "manus-1.6-lite",
|
|
141
|
+
interactive_mode: false,
|
|
142
|
+
hide_in_task_list: false,
|
|
143
|
+
};
|
|
144
|
+
const res = await fetch(`${MANUS_API_BASE}/schedule.create`, {
|
|
145
|
+
method: "POST",
|
|
146
|
+
headers: {
|
|
147
|
+
"x-manus-api-key": apiKey,
|
|
148
|
+
"Content-Type": "application/json",
|
|
149
|
+
},
|
|
150
|
+
body: JSON.stringify(body),
|
|
151
|
+
});
|
|
152
|
+
if (!res.ok) {
|
|
153
|
+
throw new ManusScheduleError(`schedule.create failed: HTTP ${res.status}`, res.status);
|
|
154
|
+
}
|
|
155
|
+
return (await res.json());
|
|
156
|
+
}
|
|
157
|
+
export async function listSchedules(apiKey) {
|
|
158
|
+
const res = await fetch(`${MANUS_API_BASE}/schedule.list`, {
|
|
159
|
+
headers: { "x-manus-api-key": apiKey },
|
|
160
|
+
});
|
|
161
|
+
if (!res.ok) {
|
|
162
|
+
throw new ManusScheduleError(`schedule.list failed: HTTP ${res.status}`, res.status);
|
|
163
|
+
}
|
|
164
|
+
const data = (await res.json());
|
|
165
|
+
// Manus may return a bare array or a wrapped object
|
|
166
|
+
if (Array.isArray(data)) {
|
|
167
|
+
return { ok: true, schedules: data };
|
|
168
|
+
}
|
|
169
|
+
return data;
|
|
170
|
+
}
|
|
171
|
+
export async function deleteSchedule(apiKey, scheduleId) {
|
|
172
|
+
const res = await fetch(`${MANUS_API_BASE}/schedule.delete`, {
|
|
173
|
+
method: "POST",
|
|
174
|
+
headers: {
|
|
175
|
+
"x-manus-api-key": apiKey,
|
|
176
|
+
"Content-Type": "application/json",
|
|
177
|
+
},
|
|
178
|
+
body: JSON.stringify({ schedule_id: scheduleId }),
|
|
179
|
+
});
|
|
180
|
+
if (!res.ok) {
|
|
181
|
+
throw new ManusScheduleError(`schedule.delete failed: HTTP ${res.status}`, res.status);
|
|
182
|
+
}
|
|
183
|
+
return (await res.json());
|
|
184
|
+
}
|
|
185
|
+
export async function pauseSchedule(apiKey, scheduleId) {
|
|
186
|
+
const res = await fetch(`${MANUS_API_BASE}/schedule.pause`, {
|
|
187
|
+
method: "POST",
|
|
188
|
+
headers: {
|
|
189
|
+
"x-manus-api-key": apiKey,
|
|
190
|
+
"Content-Type": "application/json",
|
|
191
|
+
},
|
|
192
|
+
body: JSON.stringify({ schedule_id: scheduleId }),
|
|
193
|
+
});
|
|
194
|
+
if (!res.ok) {
|
|
195
|
+
throw new ManusScheduleError(`schedule.pause failed: HTTP ${res.status}`, res.status);
|
|
196
|
+
}
|
|
197
|
+
return (await res.json());
|
|
198
|
+
}
|
|
199
|
+
export async function resumeSchedule(apiKey, scheduleId) {
|
|
200
|
+
const res = await fetch(`${MANUS_API_BASE}/schedule.resume`, {
|
|
201
|
+
method: "POST",
|
|
202
|
+
headers: {
|
|
203
|
+
"x-manus-api-key": apiKey,
|
|
204
|
+
"Content-Type": "application/json",
|
|
205
|
+
},
|
|
206
|
+
body: JSON.stringify({ schedule_id: scheduleId }),
|
|
207
|
+
});
|
|
208
|
+
if (!res.ok) {
|
|
209
|
+
throw new ManusScheduleError(`schedule.resume failed: HTTP ${res.status}`, res.status);
|
|
210
|
+
}
|
|
211
|
+
return (await res.json());
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=manus-schedule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manus-schedule.js","sourceRoot":"","sources":["../src/manus-schedule.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manus Usage/Credits API v2 client.
|
|
3
|
+
*
|
|
4
|
+
* Endpoints (open.manus.ai/docs/v2 dot-notation pattern):
|
|
5
|
+
* GET /v2/usage.get — current month's task count + credit spend
|
|
6
|
+
* GET /v2/credits.get — remaining credit balance
|
|
7
|
+
*
|
|
8
|
+
* KV cache key: `manus_usage_cache` — 60-second TTL.
|
|
9
|
+
*
|
|
10
|
+
* Threshold events emitted to Analytics Engine (AUDIT_LOG):
|
|
11
|
+
* remaining_credits < 1000 → warning
|
|
12
|
+
* remaining_credits < 100 → critical
|
|
13
|
+
*/
|
|
14
|
+
import type { Env } from "./types.js";
|
|
15
|
+
export declare class ManusUsageError extends Error {
|
|
16
|
+
readonly statusCode: number;
|
|
17
|
+
constructor(message: string, statusCode: number);
|
|
18
|
+
}
|
|
19
|
+
export interface ManusUsageData {
|
|
20
|
+
month: string;
|
|
21
|
+
spent_credits: number;
|
|
22
|
+
remaining_credits: number;
|
|
23
|
+
task_count: number;
|
|
24
|
+
}
|
|
25
|
+
export declare const USAGE_THRESHOLD_WARNING = 1000;
|
|
26
|
+
export declare const USAGE_THRESHOLD_CRITICAL = 100;
|
|
27
|
+
export declare function getUsage(apiKey: string, env: Env): Promise<{
|
|
28
|
+
data: ManusUsageData;
|
|
29
|
+
from_cache: boolean;
|
|
30
|
+
}>;
|
|
31
|
+
export declare function emitUsageThresholdIfNeeded(env: Env, data: ManusUsageData): void;
|
|
32
|
+
//# sourceMappingURL=manus-usage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manus-usage.d.ts","sourceRoot":"","sources":["../src/manus-usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC,qBAAa,eAAgB,SAAQ,KAAK;aAGtB,UAAU,EAAE,MAAM;gBADlC,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM;CAKrC;AAMD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAsCD,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAC5C,eAAO,MAAM,wBAAwB,MAAM,CAAC;AA4D5C,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,GAAG,GACP,OAAO,CAAC;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAoBxD;AAMD,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,cAAc,GACnB,IAAI,CAQN"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manus Usage/Credits API v2 client.
|
|
3
|
+
*
|
|
4
|
+
* Endpoints (open.manus.ai/docs/v2 dot-notation pattern):
|
|
5
|
+
* GET /v2/usage.get — current month's task count + credit spend
|
|
6
|
+
* GET /v2/credits.get — remaining credit balance
|
|
7
|
+
*
|
|
8
|
+
* KV cache key: `manus_usage_cache` — 60-second TTL.
|
|
9
|
+
*
|
|
10
|
+
* Threshold events emitted to Analytics Engine (AUDIT_LOG):
|
|
11
|
+
* remaining_credits < 1000 → warning
|
|
12
|
+
* remaining_credits < 100 → critical
|
|
13
|
+
*/
|
|
14
|
+
import { MANUS_API_BASE } from "./manus-common.js";
|
|
15
|
+
export class ManusUsageError extends Error {
|
|
16
|
+
statusCode;
|
|
17
|
+
constructor(message, statusCode) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.statusCode = statusCode;
|
|
20
|
+
this.name = "ManusUsageError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// KV cache
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
const CACHE_KEY = "manus_usage_cache";
|
|
27
|
+
const CACHE_TTL_SECONDS = 60;
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Threshold constants
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
export const USAGE_THRESHOLD_WARNING = 1000;
|
|
32
|
+
export const USAGE_THRESHOLD_CRITICAL = 100;
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Fetch from Manus API
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
async function fetchUsageFromApi(apiKey) {
|
|
37
|
+
const now = new Date();
|
|
38
|
+
const month = `${now.getUTCFullYear()}-${String(now.getUTCMonth() + 1).padStart(2, "0")}`;
|
|
39
|
+
// Fetch usage + credits in parallel
|
|
40
|
+
const [usageRes, creditsRes] = await Promise.all([
|
|
41
|
+
fetch(`${MANUS_API_BASE}/usage.get`, {
|
|
42
|
+
headers: { "x-manus-api-key": apiKey },
|
|
43
|
+
}),
|
|
44
|
+
fetch(`${MANUS_API_BASE}/credits.get`, {
|
|
45
|
+
headers: { "x-manus-api-key": apiKey },
|
|
46
|
+
}),
|
|
47
|
+
]);
|
|
48
|
+
if (!usageRes.ok && !creditsRes.ok) {
|
|
49
|
+
throw new ManusUsageError(`Manus usage APIs failed: usage.get HTTP ${usageRes.status}, credits.get HTTP ${creditsRes.status}`, Math.max(usageRes.status, creditsRes.status));
|
|
50
|
+
}
|
|
51
|
+
let spentCredits = 0;
|
|
52
|
+
let remainingCredits = 0;
|
|
53
|
+
let taskCount = 0;
|
|
54
|
+
if (usageRes.ok) {
|
|
55
|
+
const usageData = (await usageRes.json());
|
|
56
|
+
spentCredits = usageData.spent_credits ?? usageData.credits_used ?? 0;
|
|
57
|
+
taskCount = usageData.task_count ?? usageData.tasks_run ?? 0;
|
|
58
|
+
// usage.get may also return remaining_credits
|
|
59
|
+
if (usageData.remaining_credits !== undefined || usageData.credits_remaining !== undefined) {
|
|
60
|
+
remainingCredits = usageData.remaining_credits ?? usageData.credits_remaining ?? 0;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (creditsRes.ok) {
|
|
64
|
+
const creditsData = (await creditsRes.json());
|
|
65
|
+
// credits.get is the authoritative source for remaining balance
|
|
66
|
+
const fromCreditsApi = creditsData.remaining_credits ??
|
|
67
|
+
creditsData.credits_remaining ??
|
|
68
|
+
creditsData.balance;
|
|
69
|
+
if (fromCreditsApi !== undefined) {
|
|
70
|
+
remainingCredits = fromCreditsApi;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { month, spent_credits: spentCredits, remaining_credits: remainingCredits, task_count: taskCount };
|
|
74
|
+
}
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Public: getUsage — with KV cache
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
export async function getUsage(apiKey, env) {
|
|
79
|
+
// Check KV cache
|
|
80
|
+
const cached = await env.CARRIER_USERS.get(CACHE_KEY, "json");
|
|
81
|
+
const nowMs = Date.now();
|
|
82
|
+
if (cached && nowMs - cached.fetched_at < CACHE_TTL_SECONDS * 1000) {
|
|
83
|
+
return { data: cached.data, from_cache: true };
|
|
84
|
+
}
|
|
85
|
+
// Fetch fresh data
|
|
86
|
+
const data = await fetchUsageFromApi(apiKey);
|
|
87
|
+
// Write to KV with TTL
|
|
88
|
+
await env.CARRIER_USERS.put(CACHE_KEY, JSON.stringify({ data, fetched_at: nowMs }), { expirationTtl: CACHE_TTL_SECONDS });
|
|
89
|
+
return { data, from_cache: false };
|
|
90
|
+
}
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Threshold check — emits AE events on warning/critical
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
export function emitUsageThresholdIfNeeded(env, data) {
|
|
95
|
+
const { remaining_credits, month, task_count } = data;
|
|
96
|
+
if (remaining_credits < USAGE_THRESHOLD_CRITICAL) {
|
|
97
|
+
writeUsageThresholdAudit(env, "critical", remaining_credits, month, task_count);
|
|
98
|
+
}
|
|
99
|
+
else if (remaining_credits < USAGE_THRESHOLD_WARNING) {
|
|
100
|
+
writeUsageThresholdAudit(env, "warning", remaining_credits, month, task_count);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function writeUsageThresholdAudit(env, severity, remainingCredits, month, taskCount) {
|
|
104
|
+
try {
|
|
105
|
+
env.AUDIT_LOG.writeDataPoint({
|
|
106
|
+
blobs: [
|
|
107
|
+
"manus_usage_threshold",
|
|
108
|
+
severity,
|
|
109
|
+
month,
|
|
110
|
+
String(taskCount),
|
|
111
|
+
],
|
|
112
|
+
doubles: [remainingCredits],
|
|
113
|
+
indexes: ["manus_usage"],
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
console.error(`[manus-usage] threshold audit write failed: ${err.message}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=manus-usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manus-usage.js","sourceRoot":"","sources":["../src/manus-usage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manus webhook receiver.
|
|
3
|
+
*
|
|
4
|
+
* Receives push notifications from Manus for UI-agent tasks dispatched by
|
|
5
|
+
* tools-ui-agent.ts. Eliminates the need for client-side polling.
|
|
6
|
+
*
|
|
7
|
+
* ROUTE
|
|
8
|
+
* -----
|
|
9
|
+
* POST /manus-webhook
|
|
10
|
+
*
|
|
11
|
+
* AUTHENTICATION
|
|
12
|
+
* --------------
|
|
13
|
+
* Header: X-Manus-Signature: <hex>
|
|
14
|
+
* Payload: HMAC-SHA256(key=MANUS_WEBHOOK_SECRET, message=raw_request_body)
|
|
15
|
+
* Format: raw hex string (no "sha256=" prefix — per Manus docs).
|
|
16
|
+
*
|
|
17
|
+
* IDEMPOTENCY
|
|
18
|
+
* -----------
|
|
19
|
+
* event_id stored in CARRIER_USERS KV under key `manus_event:{event_id}` with
|
|
20
|
+
* 7-day TTL. Replayed events return 200+deduplicated without re-processing.
|
|
21
|
+
*
|
|
22
|
+
* EVENT TYPES
|
|
23
|
+
* -----------
|
|
24
|
+
* task_created — fires immediately after task.create; logged only.
|
|
25
|
+
* task_stopped — fires on completion or ask; updates audit log + AE.
|
|
26
|
+
* stop_reason:
|
|
27
|
+
* "finish" — task completed; attachment URLs logged if present.
|
|
28
|
+
* Clears any pending-ask KV entry for this task.
|
|
29
|
+
* "ask" — task paused, waiting for user input.
|
|
30
|
+
* Writes manus_pending_ask:{task_id} to CARRIER_USERS KV (24h TTL).
|
|
31
|
+
* Emits ui_agent_needs_input AE event with truncated question.
|
|
32
|
+
*
|
|
33
|
+
* PENDING-ASK KV SCHEMA
|
|
34
|
+
* ---------------------
|
|
35
|
+
* Key: manus_pending_ask:{task_id}
|
|
36
|
+
* Value: JSON { task_id, question, task_url, asked_at }
|
|
37
|
+
* TTL: 24 hours (86400 seconds)
|
|
38
|
+
*
|
|
39
|
+
* AUDIT LOG SCHEMA (Analytics Engine blobs[]):
|
|
40
|
+
* blobs[0] = "manus_webhook"
|
|
41
|
+
* blobs[1] = event_type ("task_created" | "task_stopped")
|
|
42
|
+
* blobs[2] = stop_reason ("finish" | "ask" | "ui_agent_awaiting_input" | "")
|
|
43
|
+
* blobs[3] = task_id
|
|
44
|
+
* blobs[4] = attachment_count (stringified number) or truncated question for ask events
|
|
45
|
+
* doubles[0] = latency_ms (0 for task_created)
|
|
46
|
+
* indexes[0] = task_id
|
|
47
|
+
*/
|
|
48
|
+
import type { Env } from "./types.js";
|
|
49
|
+
export interface ManusPendingAsk {
|
|
50
|
+
task_id: string;
|
|
51
|
+
question: string;
|
|
52
|
+
task_url: string;
|
|
53
|
+
asked_at: string;
|
|
54
|
+
}
|
|
55
|
+
/** 24-hour TTL for pending-ask entries. */
|
|
56
|
+
export declare const PENDING_ASK_TTL_SECONDS: number;
|
|
57
|
+
/** KV key prefix for pending-ask entries. */
|
|
58
|
+
export declare const PENDING_ASK_PREFIX = "manus_pending_ask:";
|
|
59
|
+
export declare function handleManusWebhook(request: Request, env: Env): Promise<Response>;
|
|
60
|
+
//# sourceMappingURL=manus-webhook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manus-webhook.d.ts","sourceRoot":"","sources":["../src/manus-webhook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAkDtC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AASD,2CAA2C;AAC3C,eAAO,MAAM,uBAAuB,QAAY,CAAC;AACjD,6CAA6C;AAC7C,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAQvD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,GAAG,GACP,OAAO,CAAC,QAAQ,CAAC,CAyEnB"}
|