ticlawk 0.1.15 → 0.1.16-dev.2
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 +96 -212
- package/bin/ticlawk.mjs +228 -46
- package/package.json +2 -5
- package/src/adapters/ticlawk/api.mjs +303 -26
- package/src/adapters/ticlawk/credentials.mjs +1 -2
- package/src/adapters/ticlawk/index.mjs +273 -77
- package/src/cli/agent-commands.mjs +829 -0
- package/src/core/adapter-registry.mjs +12 -28
- package/src/core/agent-cli-handlers.mjs +704 -0
- package/src/core/agent-home.mjs +89 -0
- package/src/core/config.mjs +0 -15
- package/src/core/http.mjs +204 -18
- package/src/core/reminder-ticker.mjs +70 -0
- package/src/core/runtime-contract.mjs +1 -1
- package/src/core/runtime-env.mjs +41 -5
- package/src/core/runtime-support.mjs +47 -30
- package/src/core/ticlawk-control.mjs +7 -6
- package/src/migrate/write-initial-memory.mjs +101 -0
- package/src/runtimes/_shared/standing-prompt.mjs +290 -0
- package/src/runtimes/claude-code/index.mjs +34 -34
- package/src/runtimes/claude-code/session.mjs +15 -7
- package/src/runtimes/codex/index.mjs +31 -36
- package/src/runtimes/codex/session.mjs +9 -5
- package/src/runtimes/openclaw/index.mjs +56 -16
- package/src/runtimes/openclaw/target.mjs +0 -30
- package/src/runtimes/opencode/index.mjs +30 -35
- package/src/runtimes/opencode/session.mjs +11 -2
- package/src/runtimes/pi/index.mjs +30 -36
- package/src/runtimes/pi/session.mjs +8 -2
- package/ticlawk.mjs +37 -10
- package/assets/ticlawk-concept.svg +0 -137
- package/src/adapters/telegram/index.mjs +0 -359
|
@@ -150,26 +150,21 @@ export async function updateChannel(id, updates) {
|
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
export async function postRuntimeResult(body) {
|
|
153
|
+
// Activity-only: backend records the agent_event for UI trajectory
|
|
154
|
+
// display but does NOT project it into a chat message. The agent CLI's
|
|
155
|
+
// `ticlawk message send` is the only path that produces chat rows.
|
|
153
156
|
const result = await apiFetch('/api/runtime-results', {
|
|
154
157
|
method: 'POST',
|
|
155
158
|
body: JSON.stringify(body),
|
|
156
159
|
timeout: 30000,
|
|
157
160
|
});
|
|
158
|
-
if (result?.matched === false) {
|
|
159
|
-
throw new Error('runtime result was not matched');
|
|
160
|
-
}
|
|
161
161
|
return result;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
// ──
|
|
165
|
-
|
|
166
|
-
export async function getPendingMessages() {
|
|
167
|
-
const { data } = await apiFetch('/api/messages/pending');
|
|
168
|
-
return data || [];
|
|
169
|
-
}
|
|
164
|
+
// ── Deliveries (replaces legacy message_jobs poll/ack) ──
|
|
170
165
|
|
|
171
|
-
export async function
|
|
172
|
-
const { data } = await apiFetch('/api/
|
|
166
|
+
export async function claimPendingDeliveries(hostId, limit = 5, excludedAgentIds = []) {
|
|
167
|
+
const { data } = await apiFetch('/api/agent/deliveries/claim-pending', {
|
|
173
168
|
method: 'POST',
|
|
174
169
|
body: JSON.stringify(withTiclawkVersion({
|
|
175
170
|
runtime_host_id: hostId,
|
|
@@ -180,41 +175,311 @@ export async function claimPendingMessages(hostId, limit = 5, excludedAgentIds =
|
|
|
180
175
|
return data || [];
|
|
181
176
|
}
|
|
182
177
|
|
|
183
|
-
export async function
|
|
184
|
-
return apiFetch(
|
|
178
|
+
export async function completeDelivery(deliveryId, hostId) {
|
|
179
|
+
return apiFetch(`/api/agent/deliveries/${deliveryId}/complete`, {
|
|
185
180
|
method: 'POST',
|
|
186
|
-
body: JSON.stringify({
|
|
181
|
+
body: JSON.stringify({ runtime_host_id: hostId }),
|
|
187
182
|
});
|
|
188
183
|
}
|
|
189
184
|
|
|
190
|
-
export async function
|
|
191
|
-
return apiFetch(`/api/
|
|
185
|
+
export async function releaseDelivery(deliveryId, hostId, reason = null) {
|
|
186
|
+
return apiFetch(`/api/agent/deliveries/${deliveryId}/release`, {
|
|
192
187
|
method: 'POST',
|
|
193
|
-
body: JSON.stringify(
|
|
188
|
+
body: JSON.stringify({ runtime_host_id: hostId, reason }),
|
|
194
189
|
});
|
|
195
190
|
}
|
|
196
191
|
|
|
197
|
-
|
|
198
|
-
|
|
192
|
+
// ── Agent-facing CLI surface (group chat tool path) ──
|
|
193
|
+
|
|
194
|
+
export async function sendAgentMessage({
|
|
195
|
+
actingAgentId,
|
|
196
|
+
conversationId,
|
|
197
|
+
text,
|
|
198
|
+
seenUpToSeq,
|
|
199
|
+
replyToMessageId,
|
|
200
|
+
runtimeHostId,
|
|
201
|
+
visibility,
|
|
202
|
+
}) {
|
|
203
|
+
const { data } = await apiFetch('/api/agent/messages/send', {
|
|
199
204
|
method: 'POST',
|
|
200
|
-
body: JSON.stringify({
|
|
205
|
+
body: JSON.stringify({
|
|
206
|
+
acting_as_agent_id: actingAgentId,
|
|
207
|
+
conversation_id: conversationId,
|
|
208
|
+
text,
|
|
209
|
+
seen_up_to_seq: seenUpToSeq ?? null,
|
|
210
|
+
reply_to_message_id: replyToMessageId ?? null,
|
|
211
|
+
runtime_host_id: runtimeHostId ?? null,
|
|
212
|
+
visibility: visibility || null,
|
|
213
|
+
}),
|
|
201
214
|
});
|
|
215
|
+
return data || null;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export async function readAgentMessages({
|
|
219
|
+
actingAgentId,
|
|
220
|
+
conversationId,
|
|
221
|
+
aroundMessageId,
|
|
222
|
+
beforeSeq,
|
|
223
|
+
limit,
|
|
224
|
+
}) {
|
|
225
|
+
const params = new URLSearchParams();
|
|
226
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
227
|
+
params.set('conversation_id', conversationId);
|
|
228
|
+
if (aroundMessageId) params.set('around_message_id', aroundMessageId);
|
|
229
|
+
if (beforeSeq != null) params.set('before_seq', String(beforeSeq));
|
|
230
|
+
if (limit != null) params.set('limit', String(limit));
|
|
231
|
+
const { data } = await apiFetch(`/api/agent/messages/read?${params}`);
|
|
232
|
+
return data || [];
|
|
202
233
|
}
|
|
203
234
|
|
|
204
|
-
export async function
|
|
205
|
-
return apiFetch(
|
|
235
|
+
export async function createAgentTask({ actingAgentId, conversationId, text, title }) {
|
|
236
|
+
return apiFetch('/api/agent/tasks/create', {
|
|
206
237
|
method: 'POST',
|
|
207
|
-
body: JSON.stringify({
|
|
238
|
+
body: JSON.stringify({
|
|
239
|
+
acting_as_agent_id: actingAgentId,
|
|
240
|
+
conversation_id: conversationId,
|
|
241
|
+
text,
|
|
242
|
+
title: title ?? null,
|
|
243
|
+
}),
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export async function claimAgentTask({
|
|
248
|
+
actingAgentId, sourceMessageId, conversationId, number, leaseSeconds,
|
|
249
|
+
}) {
|
|
250
|
+
return apiFetch('/api/agent/tasks/claim', {
|
|
251
|
+
method: 'POST',
|
|
252
|
+
body: JSON.stringify({
|
|
253
|
+
acting_as_agent_id: actingAgentId,
|
|
254
|
+
source_message_id: sourceMessageId ?? null,
|
|
255
|
+
conversation_id: conversationId ?? null,
|
|
256
|
+
number: number ?? null,
|
|
257
|
+
lease_seconds: leaseSeconds ?? null,
|
|
258
|
+
}),
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export async function unclaimAgentTask({ actingAgentId, taskId }) {
|
|
263
|
+
return apiFetch('/api/agent/tasks/unclaim', {
|
|
264
|
+
method: 'POST',
|
|
265
|
+
body: JSON.stringify({
|
|
266
|
+
acting_as_agent_id: actingAgentId,
|
|
267
|
+
task_id: taskId,
|
|
268
|
+
}),
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export async function reactToMessage({
|
|
273
|
+
actingAgentId, messageId, emoji, remove,
|
|
274
|
+
}) {
|
|
275
|
+
return apiFetch(`/api/agent/messages/${encodeURIComponent(messageId)}/reactions`, {
|
|
276
|
+
method: remove ? 'DELETE' : 'POST',
|
|
277
|
+
body: JSON.stringify({
|
|
278
|
+
acting_as_agent_id: actingAgentId,
|
|
279
|
+
emoji,
|
|
280
|
+
}),
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export async function updateAgentTask({ actingAgentId, taskId, status }) {
|
|
285
|
+
return apiFetch('/api/agent/tasks/update', {
|
|
286
|
+
method: 'POST',
|
|
287
|
+
body: JSON.stringify({
|
|
288
|
+
acting_as_agent_id: actingAgentId,
|
|
289
|
+
task_id: taskId,
|
|
290
|
+
status,
|
|
291
|
+
}),
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export async function listAgentTasks({ actingAgentId, conversationId }) {
|
|
296
|
+
const params = new URLSearchParams();
|
|
297
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
298
|
+
if (conversationId) params.set('conversation_id', conversationId);
|
|
299
|
+
const { data } = await apiFetch(`/api/agent/tasks/list?${params}`);
|
|
300
|
+
return data || [];
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export async function getConversationMembers({ actingAgentId, conversationId }) {
|
|
304
|
+
const params = new URLSearchParams();
|
|
305
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
306
|
+
const res = await apiFetch(`/api/agent/conversations/${conversationId}/members?${params}`);
|
|
307
|
+
return res || { data: [], conversation: null };
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export async function getAgentServerInfo({ actingAgentId }) {
|
|
311
|
+
const params = new URLSearchParams();
|
|
312
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
313
|
+
return apiFetch(`/api/agent/server-info?${params}`);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// ── Reminders ──
|
|
317
|
+
|
|
318
|
+
export async function scheduleAgentReminder({
|
|
319
|
+
actingAgentId, title, fireAt, anchorConversationId, anchorMessageId,
|
|
320
|
+
}) {
|
|
321
|
+
return apiFetch('/api/agent/reminders', {
|
|
322
|
+
method: 'POST',
|
|
323
|
+
body: JSON.stringify({
|
|
324
|
+
acting_as_agent_id: actingAgentId,
|
|
325
|
+
title,
|
|
326
|
+
fire_at: fireAt,
|
|
327
|
+
anchor_conversation_id: anchorConversationId,
|
|
328
|
+
anchor_message_id: anchorMessageId ?? null,
|
|
329
|
+
}),
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export async function listAgentReminders({ actingAgentId, status }) {
|
|
334
|
+
const params = new URLSearchParams();
|
|
335
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
336
|
+
if (status) params.set('status', status);
|
|
337
|
+
const { data } = await apiFetch(`/api/agent/reminders?${params}`);
|
|
338
|
+
return data || [];
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export async function snoozeAgentReminder({ actingAgentId, reminderId, fireAt }) {
|
|
342
|
+
return apiFetch(`/api/agent/reminders/${encodeURIComponent(reminderId)}/snooze`, {
|
|
343
|
+
method: 'POST',
|
|
344
|
+
body: JSON.stringify({
|
|
345
|
+
acting_as_agent_id: actingAgentId,
|
|
346
|
+
fire_at: fireAt,
|
|
347
|
+
}),
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export async function updateAgentReminder({
|
|
352
|
+
actingAgentId, reminderId, title, fireAt,
|
|
353
|
+
}) {
|
|
354
|
+
return apiFetch(`/api/agent/reminders/${encodeURIComponent(reminderId)}`, {
|
|
355
|
+
method: 'PATCH',
|
|
356
|
+
body: JSON.stringify({
|
|
357
|
+
acting_as_agent_id: actingAgentId,
|
|
358
|
+
title: title ?? null,
|
|
359
|
+
fire_at: fireAt ?? null,
|
|
360
|
+
}),
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export async function cancelAgentReminder({ actingAgentId, reminderId }) {
|
|
365
|
+
return apiFetch(`/api/agent/reminders/${encodeURIComponent(reminderId)}/cancel`, {
|
|
366
|
+
method: 'POST',
|
|
367
|
+
body: JSON.stringify({ acting_as_agent_id: actingAgentId }),
|
|
208
368
|
});
|
|
209
369
|
}
|
|
210
370
|
|
|
211
|
-
export async function
|
|
212
|
-
|
|
371
|
+
export async function getAgentReminderLog({ actingAgentId, reminderId }) {
|
|
372
|
+
const params = new URLSearchParams();
|
|
373
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
374
|
+
const { data } = await apiFetch(`/api/agent/reminders/${encodeURIComponent(reminderId)}/log?${params}`);
|
|
375
|
+
return data || [];
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export async function fireDueReminders() {
|
|
379
|
+
// System call: no acting agent. Used by the daemon's tick.
|
|
380
|
+
return apiFetch('/api/agent/reminders/fire-due', {
|
|
213
381
|
method: 'POST',
|
|
214
|
-
body:
|
|
382
|
+
body: '{}',
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
export async function checkAgentMessages({ actingAgentId, conversationId }) {
|
|
387
|
+
const params = new URLSearchParams();
|
|
388
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
389
|
+
if (conversationId) params.set('conversation_id', conversationId);
|
|
390
|
+
return apiFetch(`/api/agent/messages/check?${params}`);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export async function searchAgentMessages({
|
|
394
|
+
actingAgentId, query, conversationId, limit,
|
|
395
|
+
}) {
|
|
396
|
+
const params = new URLSearchParams();
|
|
397
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
398
|
+
params.set('q', query);
|
|
399
|
+
if (conversationId) params.set('conversation_id', conversationId);
|
|
400
|
+
if (limit != null) params.set('limit', String(limit));
|
|
401
|
+
const { data } = await apiFetch(`/api/agent/messages/search?${params}`);
|
|
402
|
+
return data || [];
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
export async function getAgentProfile({ actingAgentId, idOrHandle }) {
|
|
406
|
+
const params = new URLSearchParams();
|
|
407
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
408
|
+
return apiFetch(`/api/agent/profile/${encodeURIComponent(idOrHandle)}?${params}`);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
export async function patchAgentProfile({
|
|
412
|
+
actingAgentId, displayName, description, avatarUrl,
|
|
413
|
+
}) {
|
|
414
|
+
return apiFetch('/api/agent/profile', {
|
|
415
|
+
method: 'PATCH',
|
|
416
|
+
body: JSON.stringify({
|
|
417
|
+
acting_as_agent_id: actingAgentId,
|
|
418
|
+
display_name: displayName ?? null,
|
|
419
|
+
description: description ?? null,
|
|
420
|
+
avatar_url: avatarUrl ?? null,
|
|
421
|
+
}),
|
|
215
422
|
});
|
|
216
423
|
}
|
|
217
424
|
|
|
425
|
+
export async function uploadAgentAttachment({
|
|
426
|
+
actingAgentId, filename, contentType, dataBase64,
|
|
427
|
+
}) {
|
|
428
|
+
return apiFetch('/api/agent/attachments', {
|
|
429
|
+
method: 'POST',
|
|
430
|
+
body: JSON.stringify({
|
|
431
|
+
acting_as_agent_id: actingAgentId,
|
|
432
|
+
filename,
|
|
433
|
+
content_type: contentType,
|
|
434
|
+
data_base64: dataBase64,
|
|
435
|
+
}),
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
export async function viewAgentAttachment({ actingAgentId, assetId }) {
|
|
440
|
+
const params = new URLSearchParams();
|
|
441
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
442
|
+
return apiFetch(`/api/agent/attachments/${encodeURIComponent(assetId)}?${params}`);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
export async function createAgentGroup({
|
|
446
|
+
actingAgentId, name, description, memberAgentIds,
|
|
447
|
+
}) {
|
|
448
|
+
return apiFetch('/api/agent/groups', {
|
|
449
|
+
method: 'POST',
|
|
450
|
+
body: JSON.stringify({
|
|
451
|
+
acting_as_agent_id: actingAgentId,
|
|
452
|
+
name,
|
|
453
|
+
description: description ?? null,
|
|
454
|
+
member_agent_ids: memberAgentIds || [],
|
|
455
|
+
}),
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
export async function addAgentGroupMembers({
|
|
460
|
+
actingAgentId, conversationId, agentIds,
|
|
461
|
+
}) {
|
|
462
|
+
return apiFetch(`/api/agent/groups/${encodeURIComponent(conversationId)}/members`, {
|
|
463
|
+
method: 'POST',
|
|
464
|
+
body: JSON.stringify({
|
|
465
|
+
acting_as_agent_id: actingAgentId,
|
|
466
|
+
agent_ids: agentIds,
|
|
467
|
+
}),
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
export async function removeAgentGroupMember({
|
|
472
|
+
actingAgentId, conversationId, agentId,
|
|
473
|
+
}) {
|
|
474
|
+
return apiFetch(
|
|
475
|
+
`/api/agent/groups/${encodeURIComponent(conversationId)}/members/${encodeURIComponent(agentId)}`,
|
|
476
|
+
{
|
|
477
|
+
method: 'DELETE',
|
|
478
|
+
body: JSON.stringify({ acting_as_agent_id: actingAgentId }),
|
|
479
|
+
},
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
|
|
218
483
|
// ── Upload ──
|
|
219
484
|
|
|
220
485
|
export async function uploadAsset(fileName, fileData, contentType, kind = 'chat_media') {
|
|
@@ -358,3 +623,15 @@ export async function getMe() {
|
|
|
358
623
|
const { data } = await apiFetch('/api/me');
|
|
359
624
|
return data || null;
|
|
360
625
|
}
|
|
626
|
+
|
|
627
|
+
export async function reportHostCapabilities({ hostId, hostLabel, runtimesHealth, daemonVersion }) {
|
|
628
|
+
return apiFetch('/api/hosts/capabilities', {
|
|
629
|
+
method: 'POST',
|
|
630
|
+
body: JSON.stringify({
|
|
631
|
+
host_id: hostId,
|
|
632
|
+
host_label: hostLabel || null,
|
|
633
|
+
runtimes_health: runtimesHealth || {},
|
|
634
|
+
daemon_version: daemonVersion || null,
|
|
635
|
+
}),
|
|
636
|
+
});
|
|
637
|
+
}
|
|
@@ -6,13 +6,12 @@
|
|
|
6
6
|
* using the connector-specific env name.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { AF_CONFIG_PATH, persistConfig, TICLAWK_CONNECTOR_API_KEY } from '../../core/config.mjs';
|
|
10
10
|
|
|
11
11
|
export function persistApiCredential(apiKey) {
|
|
12
12
|
if (!apiKey || !apiKey.startsWith('tk_')) return;
|
|
13
13
|
|
|
14
14
|
persistConfig({
|
|
15
|
-
[AF_ADAPTER_KEY]: 'ticlawk',
|
|
16
15
|
[TICLAWK_CONNECTOR_API_KEY]: apiKey,
|
|
17
16
|
TICLAWK_SETUP_CODE: '',
|
|
18
17
|
});
|