aimeat 1.15.0 → 1.15.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/locales/en.json +4 -0
- package/dist/locales/fi.json +4 -0
- package/dist/public/views/profile/agents/tab-integration.js +12 -4
- package/dist/public/views/profile/agents-tasks-subtab.js +33 -1
- package/dist/src/routes/lib-agents.d.ts +20 -0
- package/dist/src/routes/lib-agents.d.ts.map +1 -0
- package/dist/src/routes/lib-agents.js +288 -0
- package/dist/src/routes/lib-agents.js.map +1 -0
- package/dist/src/routes/libs.d.ts +3 -0
- package/dist/src/routes/libs.d.ts.map +1 -1
- package/dist/src/routes/libs.js +16 -0
- package/dist/src/routes/libs.js.map +1 -1
- package/package.json +1 -1
package/dist/locales/en.json
CHANGED
|
@@ -458,6 +458,10 @@
|
|
|
458
458
|
"deliverable": "Deliverable",
|
|
459
459
|
"viewDeliverable": "View",
|
|
460
460
|
"deliverableGone": "The deliverable entry no longer exists.",
|
|
461
|
+
"cancel": "Cancel",
|
|
462
|
+
"cancelConfirm": "Cancel this task? Work that hasn't started will be skipped",
|
|
463
|
+
"cancelled": "Task cancelled",
|
|
464
|
+
"cancelError": "Failed to cancel task",
|
|
461
465
|
"revision_requested": "Revision requested",
|
|
462
466
|
"requestChanges": "Request changes",
|
|
463
467
|
"requestChangesTitle": "Ask the agent to revise the plan",
|
package/dist/locales/fi.json
CHANGED
|
@@ -458,6 +458,10 @@
|
|
|
458
458
|
"deliverable": "Tuotos",
|
|
459
459
|
"viewDeliverable": "Näytä",
|
|
460
460
|
"deliverableGone": "Tuotosmerkintää ei ole enää olemassa.",
|
|
461
|
+
"cancel": "Peruuta",
|
|
462
|
+
"cancelConfirm": "Peruutetaanko tämä tehtävä? Aloittamaton työ ohitetaan",
|
|
463
|
+
"cancelled": "Tehtävä peruutettu",
|
|
464
|
+
"cancelError": "Tehtävän peruutus epäonnistui",
|
|
461
465
|
"revision_requested": "Korjauspyyntö lähetetty",
|
|
462
466
|
"requestChanges": "Pyydä muutoksia",
|
|
463
467
|
"requestChangesTitle": "Pyydä agenttia muokkaamaan suunnitelmaa",
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
* during onboarding or production status (connection, platform, readiness,
|
|
5
5
|
* identity, delivery log) after completion.
|
|
6
6
|
* @version-history
|
|
7
|
+
* v1.5.0 -- 2026-05-31 -- Live-update refresh no longer toggles the full-tab loading
|
|
8
|
+
* placeholder (added a showSpinner option). During Hello Integration the agent
|
|
9
|
+
* posts steps/telemetry rapidly, so the frequent SSE ticks were re-rendering the
|
|
10
|
+
* "Loading..." state on every tick -- the tab flashed like a full reload.
|
|
7
11
|
* v1.4.0 -- 2026-05-28 -- Treat webhook with empty url as polling: status dot, label, and
|
|
8
12
|
* the webhook section all key off (webhook && webhook.url), not just
|
|
9
13
|
* the webhook object existing. A record with url="" is still polling.
|
|
@@ -48,8 +52,8 @@ export default function TabIntegration({ agent, onboarding, session, showToast,
|
|
|
48
52
|
const [updatingBundle, setUpdatingBundle] = useState(false);
|
|
49
53
|
const [copiedPrompt, setCopiedPrompt] = useState(false);
|
|
50
54
|
|
|
51
|
-
async function loadData() {
|
|
52
|
-
setLoading(true);
|
|
55
|
+
async function loadData({ showSpinner = true } = {}) {
|
|
56
|
+
if (showSpinner) setLoading(true);
|
|
53
57
|
try {
|
|
54
58
|
const [whResp, sbResp, dlResp, obResp] = await Promise.all([
|
|
55
59
|
getWebhookConfig(agentName).catch(() => null),
|
|
@@ -62,7 +66,7 @@ export default function TabIntegration({ agent, onboarding, session, showToast,
|
|
|
62
66
|
setDeliveries(dlResp?.data?.deliveries || []);
|
|
63
67
|
setPostChecklist(obResp?.data?.post_onboarding_checklist || null);
|
|
64
68
|
} catch { /* silent */ }
|
|
65
|
-
setLoading(false);
|
|
69
|
+
if (showSpinner) setLoading(false);
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
useEffect(() => { loadData(); }, [agentName]);
|
|
@@ -70,7 +74,11 @@ export default function TabIntegration({ agent, onboarding, session, showToast,
|
|
|
70
74
|
const loadRef = useRef(loadData);
|
|
71
75
|
loadRef.current = loadData;
|
|
72
76
|
useEffect(() => {
|
|
73
|
-
|
|
77
|
+
// Background refresh on every live-update WITHOUT toggling the full-tab
|
|
78
|
+
// "Loading..." placeholder. During Hello Integration the agent posts steps
|
|
79
|
+
// + telemetry rapidly, so this fires often; showing the spinner each time
|
|
80
|
+
// made the whole tab flash like a reload. Initial mount still shows it.
|
|
81
|
+
const handler = () => loadRef.current({ showSpinner: false });
|
|
74
82
|
window.addEventListener('aimeat-live-update', handler);
|
|
75
83
|
return () => window.removeEventListener('aimeat-live-update', handler);
|
|
76
84
|
}, []);
|
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
* v1.0.0 -- 2026-05-21 -- Initial creation for Agent Dashboard Phase 1
|
|
18
18
|
* v3.3.0 -- 2026-05-29 -- Add delete confirmation, "Request changes" modal for the revise-proposed-todos flow, outdated-todo history rendering, and revision_requested status.
|
|
19
19
|
* v3.3.1 -- 2026-05-30 -- Re-fetch the event log on every live-update tick while a task card is expanded. Without this, the parent refreshed the task object (todos + status) but the events list under it stayed frozen until the user closed and re-opened the card.
|
|
20
|
+
* v4.2.0 -- 2026-05-31 -- Add owner "Cancel" on active/stalled tasks: writes an
|
|
21
|
+
* agents.cancel.task.<id> marker (worker daemons self-skip before kickoff) +
|
|
22
|
+
* natively pauses the active task for immediate effect.
|
|
20
23
|
* v4.1.0 -- 2026-05-31 -- Show a completed task's deliverable: link to the
|
|
21
24
|
* agent-memory key it was published to (task.deliverableKey), fetch + preview
|
|
22
25
|
* the value on demand, and show "no longer exists" if the entry is gone.
|
|
@@ -34,7 +37,7 @@ import htm from 'htm';
|
|
|
34
37
|
const html = htm.bind(h);
|
|
35
38
|
import { t } from '/js/i18n.js';
|
|
36
39
|
import { timeAgo } from '/js/utils.js';
|
|
37
|
-
import { apiGet } from '/js/api.js';
|
|
40
|
+
import { apiGet, apiPost } from '/js/api.js';
|
|
38
41
|
import { listTasks, deleteTask, startTask, listEvents, requestChanges, createTask } from '/js/services/agent-tasks.js';
|
|
39
42
|
import { useConfirm, Modal } from '/components/Modal.js';
|
|
40
43
|
|
|
@@ -265,6 +268,32 @@ function TaskItem({ task, agentName, showToast, onRefresh }) {
|
|
|
265
268
|
);
|
|
266
269
|
}
|
|
267
270
|
|
|
271
|
+
// Cooperative cancel for a running/queued subtask: write an
|
|
272
|
+
// `agents.cancel.task.<id>` marker (owner_scope-visible, so the worker daemon
|
|
273
|
+
// self-skips before its next kickoff) AND, for immediate effect, natively
|
|
274
|
+
// pause an active task. Covers the "coordinator over-delegated; stop the work
|
|
275
|
+
// nobody is waiting for" case.
|
|
276
|
+
function handleCancel(e) {
|
|
277
|
+
e.stopPropagation();
|
|
278
|
+
confirm(
|
|
279
|
+
t('profile.agents.tasks.cancelConfirm') + ': ' + (task.title || task.id) + '?',
|
|
280
|
+
async () => {
|
|
281
|
+
try {
|
|
282
|
+
await apiPost('/v1/memory', { key: 'agents.cancel.task.' + task.id, value: [task.id], visibility: 'owner' });
|
|
283
|
+
// Immediate native stop (owner-only): pause active tasks.
|
|
284
|
+
if (task.status === 'active') {
|
|
285
|
+
try { await apiPost(`/v1/agents/${encodeURIComponent(agentName)}/tasks/${encodeURIComponent(task.id)}/pause`, {}); } catch { /* marker still applies */ }
|
|
286
|
+
}
|
|
287
|
+
showToast(t('profile.agents.tasks.cancelled'));
|
|
288
|
+
onRefresh();
|
|
289
|
+
} catch (err) {
|
|
290
|
+
showToast(err.message || t('profile.agents.tasks.cancelError'), true);
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
{ danger: true },
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
268
297
|
function handleOpenRevision(e) {
|
|
269
298
|
e.stopPropagation();
|
|
270
299
|
setShowRevisionModal(true);
|
|
@@ -454,6 +483,9 @@ function TaskItem({ task, agentName, showToast, onRefresh }) {
|
|
|
454
483
|
${t('profile.agents.tasks.requestChanges')}
|
|
455
484
|
</button>
|
|
456
485
|
`}
|
|
486
|
+
${(isActive || task.status === 'stalled') && html`
|
|
487
|
+
<button class="btn-danger btn-sm" onClick=${handleCancel}>${t('profile.agents.tasks.cancel')}</button>
|
|
488
|
+
`}
|
|
457
489
|
${(isQueued || task.status === 'draft' || isRevisionRequested) && html`
|
|
458
490
|
<button class="btn-danger btn-sm" onClick=${handleDelete}>${t('profile.agents.tasks.delete')}</button>
|
|
459
491
|
`}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file lib-agents.ts
|
|
3
|
+
* @description Serves aimeat-agents.js — the browser helper that lets an AIMEAT
|
|
4
|
+
* app (HTML+CSS) commission and observe the owner's agents from the client,
|
|
5
|
+
* without touching raw /v1/agents endpoints. Owner-side by design: the app
|
|
6
|
+
* commissions + watches work; agents do the work.
|
|
7
|
+
* @structure aimeatAgentsLib(config) -> string (IIFE attaching window.AIMEAT.agents)
|
|
8
|
+
* @usage <script src="/v1/libs/aimeat-auth.js"></script>
|
|
9
|
+
* <script src="/v1/libs/aimeat-agents.js"></script>
|
|
10
|
+
* @version-history
|
|
11
|
+
* v1.0.0 -- 2026-05-31 -- Initial: list/get, createTask/run, getTask/tasks/events,
|
|
12
|
+
* watch (SSE + poll fallback), deliverable, memory, pendingPrompts/answerPrompt.
|
|
13
|
+
* v1.1.0 -- 2026-05-31 -- Cooperative cancellation: cancelTask/cancelRun write
|
|
14
|
+
* `agents.cancel.*` memory markers (owner_scope-visible) that worker daemons
|
|
15
|
+
* honour before kickoff; cancelTask also natively pauses/deletes for
|
|
16
|
+
* immediate effect. cancelledTaskIds() reads the union.
|
|
17
|
+
*/
|
|
18
|
+
import type { AimeatConfig } from '../config.js';
|
|
19
|
+
export declare function aimeatAgentsLib(config: AimeatConfig): string;
|
|
20
|
+
//# sourceMappingURL=lib-agents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib-agents.d.ts","sourceRoot":"","sources":["../../../src/routes/lib-agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA8R5D"}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
export function aimeatAgentsLib(config) {
|
|
2
|
+
return `// aimeat-agents.js — commission & observe your agents from an AIMEAT app
|
|
3
|
+
// Node: ${config.nodeId} | Generated: ${new Date().toISOString()}
|
|
4
|
+
// Requires: aimeat-auth.js loaded first.
|
|
5
|
+
//
|
|
6
|
+
// Quick start:
|
|
7
|
+
// const list = await AIMEAT.agents.list();
|
|
8
|
+
// const { id } = await AIMEAT.agents.createTask('my-agent', {
|
|
9
|
+
// title: 'Summarise', description: 'Write a one-paragraph summary of X.' });
|
|
10
|
+
// const stop = AIMEAT.agents.watch('my-agent', id, (task, events) => {
|
|
11
|
+
// render(events);
|
|
12
|
+
// if (task.status === 'done') { stop();
|
|
13
|
+
// AIMEAT.agents.deliverable('my-agent', id).then(d =>
|
|
14
|
+
// d && (d.gone ? showGone() : show(d.value))); }
|
|
15
|
+
// });
|
|
16
|
+
//
|
|
17
|
+
// Or one call (best for task-runner agents that auto-activate):
|
|
18
|
+
// const { task, deliverable } = await AIMEAT.agents.run('my-agent',
|
|
19
|
+
// { description: '...' }, { onProgress: (t, ev) => render(ev) });
|
|
20
|
+
//
|
|
21
|
+
// Errors throw an Error with a '.code' (NOT_FOUND, FORBIDDEN, UNKNOWN, TIMEOUT).
|
|
22
|
+
(function(global) {
|
|
23
|
+
'use strict';
|
|
24
|
+
|
|
25
|
+
function getSession() {
|
|
26
|
+
if (!global.AIMEAT || !global.AIMEAT.auth) {
|
|
27
|
+
throw new Error('AIMEAT.auth is required. Include aimeat-auth.js before aimeat-agents.js');
|
|
28
|
+
}
|
|
29
|
+
const s = global.AIMEAT.auth.getSession();
|
|
30
|
+
if (!s) throw new Error('Not logged in. Call AIMEAT.auth.login() first.');
|
|
31
|
+
return s;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function authFetch(path, opts) { return getSession().fetch(path, opts); }
|
|
35
|
+
var enc = encodeURIComponent;
|
|
36
|
+
|
|
37
|
+
// session.fetch returns the parsed AIMEAT envelope { ok, data, error }.
|
|
38
|
+
function unwrap(r, action) {
|
|
39
|
+
if (!r || !r.ok) {
|
|
40
|
+
var err = new Error((r && r.error && r.error.message) || (action + ' failed'));
|
|
41
|
+
err.code = (r && r.error && r.error.code) || 'UNKNOWN';
|
|
42
|
+
throw err;
|
|
43
|
+
}
|
|
44
|
+
return r.data;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 30s cache for list() so apps can call it on every render cheaply.
|
|
48
|
+
var _agentsCache = null;
|
|
49
|
+
// 10s cache for the cancelled-task-id set.
|
|
50
|
+
var _cancelSetCache = null;
|
|
51
|
+
|
|
52
|
+
var agents = {
|
|
53
|
+
/** List the owner's agents. opts.activeOnly filters to ones seen recently.
|
|
54
|
+
* opts.fresh bypasses the 30s cache. */
|
|
55
|
+
async list(opts) {
|
|
56
|
+
var now = Date.now();
|
|
57
|
+
if (!(opts && opts.fresh) && _agentsCache && (now - _agentsCache.t) < 30000) return _agentsCache.v;
|
|
58
|
+
var data = unwrap(await authFetch('/v1/agents'), 'list agents');
|
|
59
|
+
var v = data.agents || [];
|
|
60
|
+
_agentsCache = { v: v, t: now };
|
|
61
|
+
return (opts && opts.activeOnly) ? v.filter(function(a) { return !!a.last_seen; }) : v;
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
/** One agent by name (or GAII), or null. */
|
|
65
|
+
async get(name) {
|
|
66
|
+
var all = await agents.list();
|
|
67
|
+
return all.find(function(a) { return a.name === name || a.gaii === name; }) || null;
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
/** Commission a task for an agent. Returns the created task ({ id, status, ... }).
|
|
71
|
+
* Created 'queued' by default; task-runner agents auto-activate it. */
|
|
72
|
+
async createTask(name, task) {
|
|
73
|
+
if (!task || !task.description) throw new Error('createTask requires { description }');
|
|
74
|
+
var body = {
|
|
75
|
+
title: task.title || task.description.slice(0, 80),
|
|
76
|
+
description: task.description,
|
|
77
|
+
status: task.status || 'queued',
|
|
78
|
+
};
|
|
79
|
+
var data = unwrap(await authFetch('/v1/agents/' + enc(name) + '/tasks', {
|
|
80
|
+
method: 'POST', body: JSON.stringify(body),
|
|
81
|
+
}), 'create task');
|
|
82
|
+
return data.task;
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
/** Get a single task. */
|
|
86
|
+
async getTask(name, id) {
|
|
87
|
+
return unwrap(await authFetch('/v1/agents/' + enc(name) + '/tasks/' + enc(id)), 'get task').task;
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
/** List an agent's tasks. opts.status filters (queued|active|done|failed|...). */
|
|
91
|
+
async tasks(name, opts) {
|
|
92
|
+
var q = '?per_page=100' + (opts && opts.status ? ('&status=' + enc(opts.status)) : '');
|
|
93
|
+
return unwrap(await authFetch('/v1/agents/' + enc(name) + '/tasks' + q), 'list tasks').tasks || [];
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
/** The task's event log (oldest-first). */
|
|
97
|
+
async events(name, id) {
|
|
98
|
+
return unwrap(await authFetch('/v1/agents/' + enc(name) + '/tasks/' + enc(id) + '/events'), 'list events').events || [];
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
/** Live-watch a task: calls onUpdate(task, events) on every server change
|
|
102
|
+
* (SSE) plus a periodic poll as a safety net. Returns an unsubscribe fn. */
|
|
103
|
+
watch(name, id, onUpdate, opts) {
|
|
104
|
+
var stopped = false, es = null, pollTimer = null, debTimer = null;
|
|
105
|
+
var pollMs = (opts && opts.pollMs) || 15000;
|
|
106
|
+
async function refresh() {
|
|
107
|
+
if (stopped) return;
|
|
108
|
+
try {
|
|
109
|
+
var task = await agents.getTask(name, id);
|
|
110
|
+
var events = await agents.events(name, id);
|
|
111
|
+
if (!stopped && typeof onUpdate === 'function') onUpdate(task, events);
|
|
112
|
+
} catch (e) { /* transient; the poll/next tick retries */ }
|
|
113
|
+
}
|
|
114
|
+
function debounced() { clearTimeout(debTimer); debTimer = setTimeout(refresh, 400); }
|
|
115
|
+
refresh();
|
|
116
|
+
pollTimer = setInterval(refresh, pollMs);
|
|
117
|
+
(async function() {
|
|
118
|
+
try {
|
|
119
|
+
var tk = unwrap(await authFetch('/v1/events/ticket', { method: 'POST' }), 'open event stream');
|
|
120
|
+
if (stopped || !tk || !tk.ticket) return;
|
|
121
|
+
es = new EventSource('/v1/events?ticket=' + enc(tk.ticket));
|
|
122
|
+
es.onmessage = debounced;
|
|
123
|
+
} catch (e) { /* SSE unavailable — poll fallback already running */ }
|
|
124
|
+
})();
|
|
125
|
+
return function unsubscribe() {
|
|
126
|
+
stopped = true;
|
|
127
|
+
if (es) { try { es.close(); } catch (e) {} es = null; }
|
|
128
|
+
clearInterval(pollTimer); clearTimeout(debTimer);
|
|
129
|
+
};
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
/** Read the task's published deliverable (task.deliverableKey) from the
|
|
133
|
+
* agent's memory. Returns { key, value } | { key, gone:true } | null. */
|
|
134
|
+
async deliverable(name, id) {
|
|
135
|
+
var task = await agents.getTask(name, id);
|
|
136
|
+
var key = task && task.deliverableKey;
|
|
137
|
+
if (!key) return null;
|
|
138
|
+
var data = unwrap(await authFetch('/v1/memory?agent=' + enc(task.agentGaii) + '&prefix=' + enc(key) + '&per_page=20'), 'read deliverable');
|
|
139
|
+
var items = data.items || [];
|
|
140
|
+
var found = items.find(function(i) { return i.key === key; });
|
|
141
|
+
return found ? { key: key, value: found.value } : { key: key, gone: true };
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
/** Read a specific memory entry under an agent's namespace (or null). */
|
|
145
|
+
async memory(name, key) {
|
|
146
|
+
var a = await agents.get(name);
|
|
147
|
+
var gaii = (a && a.gaii) || name;
|
|
148
|
+
var data = unwrap(await authFetch('/v1/memory?agent=' + enc(gaii) + '&prefix=' + enc(key) + '&per_page=20'), 'read agent memory');
|
|
149
|
+
var items = data.items || [];
|
|
150
|
+
var found = items.find(function(i) { return i.key === key; });
|
|
151
|
+
return found ? found.value : null;
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
/** Agent questions awaiting an answer: outbound option-prompts with no reply
|
|
155
|
+
* yet. Each is { message_id, prompt_id, question, options, allow_other }. */
|
|
156
|
+
async pendingPrompts(name) {
|
|
157
|
+
var data = unwrap(await authFetch('/v1/agents/' + enc(name) + '/messages?per_page=100'), 'list messages');
|
|
158
|
+
var msgs = data.messages || [];
|
|
159
|
+
var answered = {};
|
|
160
|
+
msgs.forEach(function(m) {
|
|
161
|
+
var pa = m.metadata && (m.metadata.promptAnswer || m.metadata.prompt_answer);
|
|
162
|
+
var pid = pa && (pa.promptId || pa.prompt_id);
|
|
163
|
+
if (pid) answered[pid] = true;
|
|
164
|
+
});
|
|
165
|
+
var out = [];
|
|
166
|
+
msgs.forEach(function(m) {
|
|
167
|
+
if (m.direction !== 'outbound') return;
|
|
168
|
+
var p = m.metadata && m.metadata.prompt;
|
|
169
|
+
if (!p) return;
|
|
170
|
+
var pid = p.promptId || p.prompt_id;
|
|
171
|
+
if (!pid || answered[pid]) return;
|
|
172
|
+
out.push({
|
|
173
|
+
message_id: m.id,
|
|
174
|
+
prompt_id: pid,
|
|
175
|
+
question: p.question,
|
|
176
|
+
options: p.options || [],
|
|
177
|
+
allow_other: (p.allowOther != null ? p.allowOther : p.allow_other) !== false,
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
return out;
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
/** Answer an agent's option-prompt (owner -> agent). choice is the chosen
|
|
184
|
+
* option text, or free text when is_other is true. */
|
|
185
|
+
async answerPrompt(name, ans) {
|
|
186
|
+
if (!ans || !ans.prompt_id || !ans.choice) throw new Error('answerPrompt requires { prompt_id, choice }');
|
|
187
|
+
return unwrap(await authFetch('/v1/agents/' + enc(name) + '/messages', {
|
|
188
|
+
method: 'POST',
|
|
189
|
+
body: JSON.stringify({
|
|
190
|
+
content: ans.choice,
|
|
191
|
+
direction: 'inbound',
|
|
192
|
+
metadata: { prompt_answer: { prompt_id: ans.prompt_id, choice: ans.choice, is_other: !!ans.is_other } },
|
|
193
|
+
}),
|
|
194
|
+
}), 'answer prompt');
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
/** Commission + watch until done/failed/stalled, then resolve
|
|
198
|
+
* { task, deliverable }. Best for task-runner agents (which auto-activate).
|
|
199
|
+
* opts: { onProgress(task, events), timeoutMs, pollMs }. */
|
|
200
|
+
async run(name, task, opts) {
|
|
201
|
+
var created = await agents.createTask(name, task);
|
|
202
|
+
var id = created.id;
|
|
203
|
+
return await new Promise(function(resolve, reject) {
|
|
204
|
+
var done = false, to = null;
|
|
205
|
+
var stop = agents.watch(name, id, async function(t, events) {
|
|
206
|
+
if (opts && opts.onProgress) { try { opts.onProgress(t, events); } catch (e) {} }
|
|
207
|
+
if (!done && (t.status === 'done' || t.status === 'failed' || t.status === 'stalled')) {
|
|
208
|
+
done = true; if (to) clearTimeout(to); stop();
|
|
209
|
+
var deliverable = t.status === 'done' ? await agents.deliverable(name, id).catch(function() { return null; }) : null;
|
|
210
|
+
resolve({ task: t, deliverable: deliverable });
|
|
211
|
+
}
|
|
212
|
+
}, opts);
|
|
213
|
+
if (opts && opts.timeoutMs > 0) {
|
|
214
|
+
to = setTimeout(function() {
|
|
215
|
+
if (!done) { done = true; stop(); var e = new Error('run() timed out'); e.code = 'TIMEOUT'; e.taskId = id; reject(e); }
|
|
216
|
+
}, opts.timeoutMs);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
/** Cooperative-cancel a task. Writes a cancel marker the worker daemon
|
|
222
|
+
* honours before its next kickoff (so abandoned/speculative subtasks never
|
|
223
|
+
* start), AND, for immediate effect, natively pauses an active task or
|
|
224
|
+
* deletes a queued one (owner-only ops; best-effort). Returns
|
|
225
|
+
* { marked:true, native:'paused'|'deleted'|null }. */
|
|
226
|
+
async cancelTask(name, taskId, opts) {
|
|
227
|
+
await authFetch('/v1/memory', { method: 'POST', body: JSON.stringify({
|
|
228
|
+
key: 'agents.cancel.task.' + taskId,
|
|
229
|
+
value: [taskId],
|
|
230
|
+
visibility: 'owner',
|
|
231
|
+
}) });
|
|
232
|
+
var native = null;
|
|
233
|
+
try {
|
|
234
|
+
var t = await agents.getTask(name, taskId);
|
|
235
|
+
var st = t && t.status;
|
|
236
|
+
if (st === 'active') {
|
|
237
|
+
var r = await authFetch('/v1/agents/' + enc(name) + '/tasks/' + enc(taskId) + '/pause', { method: 'POST' });
|
|
238
|
+
if (r && r.ok) native = 'paused';
|
|
239
|
+
} else if (st === 'queued' || st === 'draft') {
|
|
240
|
+
var r2 = await authFetch('/v1/agents/' + enc(name) + '/tasks/' + enc(taskId), { method: 'DELETE' });
|
|
241
|
+
if (r2 && r2.ok) native = 'deleted';
|
|
242
|
+
}
|
|
243
|
+
} catch (e) { /* native stop is best-effort; the marker still applies */ }
|
|
244
|
+
if (opts && opts.invalidate !== false) _cancelSetCache = null;
|
|
245
|
+
return { marked: true, native: native };
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
/** Cancel a whole run/batch: write one marker listing many task ids
|
|
249
|
+
* (key agents.cancel.run.<run>). Workers union all agents.cancel.* markers. */
|
|
250
|
+
async cancelRun(run, taskIds) {
|
|
251
|
+
if (!run || !Array.isArray(taskIds)) throw new Error('cancelRun requires (run, taskIds[])');
|
|
252
|
+
await authFetch('/v1/memory', { method: 'POST', body: JSON.stringify({
|
|
253
|
+
key: 'agents.cancel.run.' + run,
|
|
254
|
+
value: taskIds.map(String),
|
|
255
|
+
visibility: 'owner',
|
|
256
|
+
}) });
|
|
257
|
+
_cancelSetCache = null;
|
|
258
|
+
return { marked: true, count: taskIds.length };
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
/** The set (array) of task ids cancelled via any agents.cancel.* marker
|
|
262
|
+
* visible to the owner. 10s cache. */
|
|
263
|
+
async cancelledTaskIds(opts) {
|
|
264
|
+
var now = Date.now();
|
|
265
|
+
if (!(opts && opts.fresh) && _cancelSetCache && (now - _cancelSetCache.t) < 10000) return _cancelSetCache.v;
|
|
266
|
+
var data = unwrap(await authFetch('/v1/memory?owner_scope=true&prefix=' + enc('agents.cancel.') + '&per_page=100'), 'read cancel markers');
|
|
267
|
+
var set = {};
|
|
268
|
+
(data.items || []).forEach(function (it) {
|
|
269
|
+
var v = it.value;
|
|
270
|
+
if (Array.isArray(v)) v.forEach(function (x) { set[String(x)] = true; });
|
|
271
|
+
else if (v && typeof v === 'object') Object.keys(v).forEach(function (k) { set[k] = true; });
|
|
272
|
+
});
|
|
273
|
+
var v = Object.keys(set);
|
|
274
|
+
_cancelSetCache = { v: v, t: now };
|
|
275
|
+
return v;
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
/** Clear the cached agent list (call after creating/deleting an agent). */
|
|
279
|
+
invalidateCache() { _agentsCache = null; _cancelSetCache = null; },
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
if (!global.AIMEAT) global.AIMEAT = {};
|
|
283
|
+
global.AIMEAT.agents = agents;
|
|
284
|
+
|
|
285
|
+
})(typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : this);
|
|
286
|
+
`;
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=lib-agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib-agents.js","sourceRoot":"","sources":["../../../src/routes/lib-agents.ts"],"names":[],"mappings":"AAmBA,MAAM,UAAU,eAAe,CAAC,MAAoB;IAClD,OAAO;WACE,MAAM,CAAC,MAAM,iBAAiB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2RhE,CAAC;AACF,CAAC"}
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* @structure libsRouter route registration; aimeatAuthLib browser auth/session helper; individual library imports delegated to lib-* modules.
|
|
5
5
|
* @usage app.use(libsRouter(config, storage)) from the server setup.
|
|
6
6
|
* @version-history
|
|
7
|
+
* v1.11.0 - 2026-05-31 - Add aimeat-agents.js — apps commission & observe the
|
|
8
|
+
* owner's agents (list, createTask/run, watch via SSE, deliverables,
|
|
9
|
+
* option-prompt answer loop). Registered as a route + in the /v1/libs catalogue.
|
|
7
10
|
* v1.10.0 - 2026-05-29 - Add aimeat-ai.js — AI completion using the user's
|
|
8
11
|
* OpenRouter key (apps reach /v1/ai/complete; budget + per-app quotas
|
|
9
12
|
* enforced server-side). Registered both as a route and in the /v1/libs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libs.d.ts","sourceRoot":"","sources":["../../../src/routes/libs.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"libs.d.ts","sourceRoot":"","sources":["../../../src/routes/libs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,MAAM,EAAiB,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAmBvD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAwM1E"}
|
package/dist/src/routes/libs.js
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* @structure libsRouter route registration; aimeatAuthLib browser auth/session helper; individual library imports delegated to lib-* modules.
|
|
5
5
|
* @usage app.use(libsRouter(config, storage)) from the server setup.
|
|
6
6
|
* @version-history
|
|
7
|
+
* v1.11.0 - 2026-05-31 - Add aimeat-agents.js — apps commission & observe the
|
|
8
|
+
* owner's agents (list, createTask/run, watch via SSE, deliverables,
|
|
9
|
+
* option-prompt answer loop). Registered as a route + in the /v1/libs catalogue.
|
|
7
10
|
* v1.10.0 - 2026-05-29 - Add aimeat-ai.js — AI completion using the user's
|
|
8
11
|
* OpenRouter key (apps reach /v1/ai/complete; budget + per-app quotas
|
|
9
12
|
* enforced server-side). Registered both as a route and in the /v1/libs
|
|
@@ -23,6 +26,7 @@ import { aimeatAudioLib } from './lib-audio.js';
|
|
|
23
26
|
import { aimeatSpeechLib } from './lib-speech.js';
|
|
24
27
|
import { aimeatCapabilitiesLib } from './lib-capabilities.js';
|
|
25
28
|
import { aimeatAiLib } from './lib-ai.js';
|
|
29
|
+
import { aimeatAgentsLib } from './lib-agents.js';
|
|
26
30
|
function sendJavascriptLibrary(res, source) {
|
|
27
31
|
res.set('Cache-Control', 'no-store');
|
|
28
32
|
res.set('Pragma', 'no-cache');
|
|
@@ -79,6 +83,10 @@ export function libsRouter(config, _storage) {
|
|
|
79
83
|
router.get('/v1/libs/aimeat-ai.js', (_req, res) => {
|
|
80
84
|
sendJavascriptLibrary(res, aimeatAiLib(config));
|
|
81
85
|
});
|
|
86
|
+
// GET /v1/libs/aimeat-agents.js — commission & observe the owner's agents
|
|
87
|
+
router.get('/v1/libs/aimeat-agents.js', (_req, res) => {
|
|
88
|
+
sendJavascriptLibrary(res, aimeatAgentsLib(config));
|
|
89
|
+
});
|
|
82
90
|
// GET /v1/libs/ — List available libraries
|
|
83
91
|
router.get('/v1/libs', (_req, res) => {
|
|
84
92
|
res.json({
|
|
@@ -169,6 +177,14 @@ export function libsRouter(config, _storage) {
|
|
|
169
177
|
include: `<script src="${config.baseUrl}/v1/libs/aimeat-ai.js"></script>`,
|
|
170
178
|
requires: 'aimeat-auth',
|
|
171
179
|
},
|
|
180
|
+
{
|
|
181
|
+
name: 'aimeat-agents',
|
|
182
|
+
url: '/v1/libs/aimeat-agents.js',
|
|
183
|
+
description: 'Agents: list, commission tasks (createTask/run), watch progress live (SSE), read deliverables, and the ask-the-user option-prompt loop.',
|
|
184
|
+
size_estimate: '~7KB',
|
|
185
|
+
include: `<script src="${config.baseUrl}/v1/libs/aimeat-agents.js"></script>`,
|
|
186
|
+
requires: 'aimeat-auth',
|
|
187
|
+
},
|
|
172
188
|
],
|
|
173
189
|
});
|
|
174
190
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libs.js","sourceRoot":"","sources":["../../../src/routes/libs.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"libs.js","sourceRoot":"","sources":["../../../src/routes/libs.ts"],"names":[],"mappings":"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"}
|