ticlawk 0.1.16-dev.2 → 0.1.16-dev.20
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 +14 -2
- package/bin/ticlawk.mjs +207 -25
- package/package.json +1 -1
- package/src/adapters/ticlawk/api.mjs +230 -22
- package/src/adapters/ticlawk/credentials.mjs +41 -1
- package/src/adapters/ticlawk/index.mjs +196 -195
- package/src/adapters/ticlawk/wake-client.mjs +1 -1
- package/src/cli/agent-commands.mjs +601 -35
- package/src/core/agent-cli-handlers.mjs +448 -20
- package/src/core/agent-home.mjs +50 -10
- package/src/core/argv.mjs +11 -1
- package/src/core/http.mjs +126 -0
- package/src/core/runtime-env.mjs +7 -0
- package/src/core/runtime-support.mjs +101 -30
- package/src/migrate/write-initial-memory.mjs +5 -5
- package/src/runtimes/_shared/brand.mjs +1 -0
- package/src/runtimes/_shared/goal-task-protocol.mjs +228 -0
- package/src/runtimes/_shared/standing-prompt.mjs +120 -278
- package/src/runtimes/_shared/wake-prompt.mjs +173 -0
- package/src/runtimes/claude-code/index.mjs +30 -108
- package/src/runtimes/codex/index.mjs +114 -23
- package/src/runtimes/openclaw/index.mjs +16 -26
- package/src/runtimes/opencode/index.mjs +42 -36
- package/src/runtimes/opencode/session.mjs +5 -4
- package/src/runtimes/pi/index.mjs +39 -31
- package/src/runtimes/pi/session.mjs +5 -2
- package/src/adapters/ticlawk/cards.mjs +0 -149
- package/src/core/media/outbound.mjs +0 -163
package/README.md
CHANGED
|
@@ -216,8 +216,12 @@ Agent CLI (run inside an agent runtime; requires TICLAWK_RUNTIME_AGENT_ID):
|
|
|
216
216
|
ticlawk message read --target <t> [opts]
|
|
217
217
|
ticlawk task claim --message-id <id>
|
|
218
218
|
ticlawk task update --task-id <id> --status <s>
|
|
219
|
-
ticlawk task list [--target <t>]
|
|
219
|
+
ticlawk task list [--target <t>] # group admins see the full task board
|
|
220
|
+
ticlawk charter get --target <t>
|
|
220
221
|
ticlawk group members --target <t>
|
|
222
|
+
ticlawk group list
|
|
223
|
+
ticlawk agent list
|
|
224
|
+
ticlawk dashboard get --conversation-id <id>
|
|
221
225
|
ticlawk server info [--refresh]
|
|
222
226
|
|
|
223
227
|
Commands:
|
|
@@ -226,7 +230,15 @@ Commands:
|
|
|
226
230
|
profile list or switch saved local identities
|
|
227
231
|
message send/read chat messages (agent CLI surface)
|
|
228
232
|
task claim/update/list tasks (agent CLI surface)
|
|
229
|
-
|
|
233
|
+
charter get/set conversation goal and role spec (agent CLI surface)
|
|
234
|
+
group create/list/delete groups, manage charters/members (agent CLI surface)
|
|
235
|
+
dashboard set/get conversation dashboards (agent CLI surface)
|
|
236
|
+
briefing publish/get owner briefings (agent CLI surface)
|
|
237
|
+
agent list/create/delete owned agent slots (agent CLI surface)
|
|
238
|
+
service publish/list/call shared services (agent CLI surface)
|
|
239
|
+
credential request owner-filled credentials (agent CLI surface)
|
|
240
|
+
reminder schedule/list/snooze/cancel reminders (agent CLI surface)
|
|
241
|
+
attachment view private chat assets (agent CLI surface)
|
|
230
242
|
server server-info introspection (agent CLI surface)
|
|
231
243
|
install-daemon install or refresh the background daemon
|
|
232
244
|
update update the npm package and refresh the daemon
|
package/bin/ticlawk.mjs
CHANGED
|
@@ -30,9 +30,27 @@ import { getInstallDaemonHelp, runInstallDaemon } from '../src/core/daemon-insta
|
|
|
30
30
|
import { runSetupReadiness } from '../src/core/setup-readiness.mjs';
|
|
31
31
|
import {
|
|
32
32
|
AGENT_COMMAND_HELP,
|
|
33
|
-
runAttachmentUploadCommand,
|
|
34
33
|
runAttachmentViewCommand,
|
|
35
34
|
runGroupCreateCommand,
|
|
35
|
+
runWorkstreamCharterGetCommand,
|
|
36
|
+
runWorkstreamCharterSetCommand,
|
|
37
|
+
runWorkstreamCreateCommand,
|
|
38
|
+
runWorkstreamDeleteCommand,
|
|
39
|
+
runWorkstreamListCommand,
|
|
40
|
+
runAgentListCommand,
|
|
41
|
+
runAgentCreateCommand,
|
|
42
|
+
runAgentDeleteCommand,
|
|
43
|
+
runDashboardSetCommand,
|
|
44
|
+
runDashboardGetCommand,
|
|
45
|
+
runCredentialRequestCommand,
|
|
46
|
+
runBriefingPublishCommand,
|
|
47
|
+
runBriefingGetCommand,
|
|
48
|
+
runServiceCreateCommand,
|
|
49
|
+
runServiceUpdateCommand,
|
|
50
|
+
runServiceDeleteCommand,
|
|
51
|
+
runServiceListCommand,
|
|
52
|
+
runServiceInfoCommand,
|
|
53
|
+
runServiceCallCommand,
|
|
36
54
|
runGroupMembersAddCommand,
|
|
37
55
|
runGroupMembersCommand,
|
|
38
56
|
runGroupMembersRemoveCommand,
|
|
@@ -97,8 +115,12 @@ Agent CLI (run inside an agent runtime; requires TICLAWK_RUNTIME_AGENT_ID):
|
|
|
97
115
|
ticlawk message read --target <t> [opts]
|
|
98
116
|
ticlawk task claim --message-id <id>
|
|
99
117
|
ticlawk task update --task-id <id> --status <s>
|
|
100
|
-
ticlawk task list [--target <t>]
|
|
118
|
+
ticlawk task list [--target <t>] # group admins see the full task board
|
|
119
|
+
ticlawk charter get --target <t>
|
|
101
120
|
ticlawk group members --target <t>
|
|
121
|
+
ticlawk group list
|
|
122
|
+
ticlawk agent list
|
|
123
|
+
ticlawk dashboard get --conversation-id <id>
|
|
102
124
|
ticlawk server info [--refresh]
|
|
103
125
|
|
|
104
126
|
Commands:
|
|
@@ -107,7 +129,15 @@ Commands:
|
|
|
107
129
|
profile list or switch saved local identities
|
|
108
130
|
message send/read chat messages (agent CLI surface)
|
|
109
131
|
task claim/update/list tasks (agent CLI surface)
|
|
110
|
-
|
|
132
|
+
charter get/set conversation goal and role spec (agent CLI surface)
|
|
133
|
+
group create/list/delete groups, manage charters/members (agent CLI surface)
|
|
134
|
+
dashboard set/get conversation dashboards (agent CLI surface)
|
|
135
|
+
briefing publish/get owner briefings (agent CLI surface)
|
|
136
|
+
agent list/create/delete owned agent slots (agent CLI surface)
|
|
137
|
+
service publish/list/call shared services (agent CLI surface)
|
|
138
|
+
credential request owner-filled credentials (agent CLI surface)
|
|
139
|
+
reminder schedule/list/snooze/cancel reminders (agent CLI surface)
|
|
140
|
+
attachment view private chat assets (agent CLI surface)
|
|
111
141
|
server server-info introspection (agent CLI surface)
|
|
112
142
|
install-daemon install or refresh the background daemon
|
|
113
143
|
update update the npm package and refresh the daemon
|
|
@@ -179,6 +209,10 @@ function printHelp(helpPath, args = {}) {
|
|
|
179
209
|
console.log(getInstallDaemonHelp());
|
|
180
210
|
return;
|
|
181
211
|
}
|
|
212
|
+
if (AGENT_COMMAND_HELP[head]) {
|
|
213
|
+
console.log(AGENT_COMMAND_HELP[head]);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
182
216
|
printUsage();
|
|
183
217
|
}
|
|
184
218
|
|
|
@@ -358,24 +392,6 @@ async function main() {
|
|
|
358
392
|
process.exit(1);
|
|
359
393
|
}
|
|
360
394
|
|
|
361
|
-
if (command === 'profile') {
|
|
362
|
-
const sub = args._[1];
|
|
363
|
-
if (args.help || args.h || !sub) {
|
|
364
|
-
console.log(AGENT_COMMAND_HELP.profile);
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
if (sub === 'show') {
|
|
368
|
-
process.exitCode = await runProfileShowCommand(args);
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
if (sub === 'update') {
|
|
372
|
-
process.exitCode = await runProfileUpdateCommand(args);
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
console.error(`unknown profile subcommand: ${sub}`);
|
|
376
|
-
process.exit(1);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
395
|
if (command === 'reminder') {
|
|
380
396
|
const sub = args._[1];
|
|
381
397
|
if (args.help || args.h || !sub) {
|
|
@@ -416,10 +432,6 @@ async function main() {
|
|
|
416
432
|
console.log(AGENT_COMMAND_HELP.attachment);
|
|
417
433
|
return;
|
|
418
434
|
}
|
|
419
|
-
if (sub === 'upload') {
|
|
420
|
-
process.exitCode = await runAttachmentUploadCommand(args);
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
435
|
if (sub === 'view') {
|
|
424
436
|
process.exitCode = await runAttachmentViewCommand(args);
|
|
425
437
|
return;
|
|
@@ -458,6 +470,147 @@ async function main() {
|
|
|
458
470
|
process.exit(1);
|
|
459
471
|
}
|
|
460
472
|
|
|
473
|
+
if (command === 'workstream') {
|
|
474
|
+
const sub = args._[1];
|
|
475
|
+
if (args.help || args.h || !sub) {
|
|
476
|
+
console.log(AGENT_COMMAND_HELP.workstream);
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
if (sub === 'create') {
|
|
480
|
+
process.exitCode = await runWorkstreamCreateCommand(args);
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
if (sub === 'delete') {
|
|
484
|
+
process.exitCode = await runWorkstreamDeleteCommand(args);
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
if (sub === 'list') {
|
|
488
|
+
process.exitCode = await runWorkstreamListCommand(args);
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
if (sub === 'charter') {
|
|
492
|
+
const op = args._[2];
|
|
493
|
+
if (op === 'get') {
|
|
494
|
+
process.exitCode = await runWorkstreamCharterGetCommand(args);
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
if (op === 'set') {
|
|
498
|
+
process.exitCode = await runWorkstreamCharterSetCommand(args);
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
console.error(`unknown workstream charter op: ${op}`);
|
|
502
|
+
process.exit(1);
|
|
503
|
+
}
|
|
504
|
+
console.error(`unknown workstream subcommand: ${sub}`);
|
|
505
|
+
process.exit(1);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
if (command === 'agent') {
|
|
509
|
+
const sub = args._[1];
|
|
510
|
+
if (args.help || args.h || !sub) {
|
|
511
|
+
console.log(AGENT_COMMAND_HELP.agent);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
if (sub === 'list') {
|
|
515
|
+
process.exitCode = await runAgentListCommand(args);
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
if (sub === 'create') {
|
|
519
|
+
process.exitCode = await runAgentCreateCommand(args);
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
if (sub === 'delete') {
|
|
523
|
+
process.exitCode = await runAgentDeleteCommand(args);
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
console.error(`unknown agent subcommand: ${sub}`);
|
|
527
|
+
process.exit(1);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
if (command === 'service') {
|
|
531
|
+
const sub = args._[1];
|
|
532
|
+
if (args.help || args.h || !sub) {
|
|
533
|
+
console.log(AGENT_COMMAND_HELP.service);
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
if (sub === 'create') { process.exitCode = await runServiceCreateCommand(args); return; }
|
|
537
|
+
if (sub === 'update') { process.exitCode = await runServiceUpdateCommand(args); return; }
|
|
538
|
+
if (sub === 'delete') { process.exitCode = await runServiceDeleteCommand(args); return; }
|
|
539
|
+
if (sub === 'list') { process.exitCode = await runServiceListCommand(args); return; }
|
|
540
|
+
if (sub === 'info') { process.exitCode = await runServiceInfoCommand(args); return; }
|
|
541
|
+
if (sub === 'call') { process.exitCode = await runServiceCallCommand(args); return; }
|
|
542
|
+
console.error(`unknown service subcommand: ${sub}`);
|
|
543
|
+
process.exit(1);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
if (command === 'briefing') {
|
|
547
|
+
const sub = args._[1];
|
|
548
|
+
if (args.help || args.h || !sub) {
|
|
549
|
+
console.log(AGENT_COMMAND_HELP.briefing);
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
if (sub === 'publish') {
|
|
553
|
+
process.exitCode = await runBriefingPublishCommand(args);
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
if (sub === 'get') {
|
|
557
|
+
process.exitCode = await runBriefingGetCommand(args);
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
console.error(`unknown briefing subcommand: ${sub}`);
|
|
561
|
+
process.exit(1);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
if (command === 'credential') {
|
|
565
|
+
const sub = args._[1];
|
|
566
|
+
if (args.help || args.h || !sub) {
|
|
567
|
+
console.log(AGENT_COMMAND_HELP.credential);
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
if (sub === 'request') {
|
|
571
|
+
process.exitCode = await runCredentialRequestCommand(args);
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
console.error(`unknown credential subcommand: ${sub}`);
|
|
575
|
+
process.exit(1);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
if (command === 'dashboard') {
|
|
579
|
+
const sub = args._[1];
|
|
580
|
+
if (args.help || args.h || !sub) {
|
|
581
|
+
console.log(AGENT_COMMAND_HELP.dashboard);
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
if (sub === 'set') {
|
|
585
|
+
process.exitCode = await runDashboardSetCommand(args);
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
if (sub === 'get') {
|
|
589
|
+
process.exitCode = await runDashboardGetCommand(args);
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
console.error(`unknown dashboard subcommand: ${sub}`);
|
|
593
|
+
process.exit(1);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
if (command === 'charter') {
|
|
597
|
+
const sub = args._[1];
|
|
598
|
+
if (args.help || args.h || !sub) {
|
|
599
|
+
console.log(AGENT_COMMAND_HELP.charter);
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
if (sub === 'get') {
|
|
603
|
+
process.exitCode = await runWorkstreamCharterGetCommand(args);
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
if (sub === 'set') {
|
|
607
|
+
process.exitCode = await runWorkstreamCharterSetCommand(args);
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
console.error(`unknown charter subcommand: ${sub}`);
|
|
611
|
+
process.exit(1);
|
|
612
|
+
}
|
|
613
|
+
|
|
461
614
|
if (command === 'group') {
|
|
462
615
|
const sub = args._[1];
|
|
463
616
|
if (args.help || args.h || !sub) {
|
|
@@ -468,6 +621,27 @@ async function main() {
|
|
|
468
621
|
process.exitCode = await runGroupCreateCommand(args);
|
|
469
622
|
return;
|
|
470
623
|
}
|
|
624
|
+
if (sub === 'list') {
|
|
625
|
+
process.exitCode = await runWorkstreamListCommand(args);
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
if (sub === 'delete') {
|
|
629
|
+
process.exitCode = await runWorkstreamDeleteCommand(args);
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
if (sub === 'charter') {
|
|
633
|
+
const op = args._[2];
|
|
634
|
+
if (op === 'get') {
|
|
635
|
+
process.exitCode = await runWorkstreamCharterGetCommand(args);
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
if (op === 'set') {
|
|
639
|
+
process.exitCode = await runWorkstreamCharterSetCommand(args);
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
console.error(`unknown group charter op: ${op}`);
|
|
643
|
+
process.exit(1);
|
|
644
|
+
}
|
|
471
645
|
if (sub === 'members') {
|
|
472
646
|
// Same subcommand handles list / add / remove based on flags.
|
|
473
647
|
if (args.add) {
|
|
@@ -610,6 +784,14 @@ async function main() {
|
|
|
610
784
|
console.log('Restart ticlawk for the daemon to use the selected profile.');
|
|
611
785
|
return;
|
|
612
786
|
}
|
|
787
|
+
if (subcommand === 'show') {
|
|
788
|
+
process.exitCode = await runProfileShowCommand(args);
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
if (subcommand === 'update') {
|
|
792
|
+
process.exitCode = await runProfileUpdateCommand(args);
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
613
795
|
console.error(`unknown profile subcommand: ${subcommand}`);
|
|
614
796
|
process.exit(1);
|
|
615
797
|
}
|
package/package.json
CHANGED
|
@@ -149,18 +149,6 @@ export async function updateChannel(id, updates) {
|
|
|
149
149
|
return updateAgent(id, updates);
|
|
150
150
|
}
|
|
151
151
|
|
|
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.
|
|
156
|
-
const result = await apiFetch('/api/runtime-results', {
|
|
157
|
-
method: 'POST',
|
|
158
|
-
body: JSON.stringify(body),
|
|
159
|
-
timeout: 30000,
|
|
160
|
-
});
|
|
161
|
-
return result;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
152
|
// ── Deliveries (replaces legacy message_jobs poll/ack) ──
|
|
165
153
|
|
|
166
154
|
export async function claimPendingDeliveries(hostId, limit = 5, excludedAgentIds = []) {
|
|
@@ -199,6 +187,8 @@ export async function sendAgentMessage({
|
|
|
199
187
|
replyToMessageId,
|
|
200
188
|
runtimeHostId,
|
|
201
189
|
visibility,
|
|
190
|
+
mediaAssetIds,
|
|
191
|
+
metadata,
|
|
202
192
|
}) {
|
|
203
193
|
const { data } = await apiFetch('/api/agent/messages/send', {
|
|
204
194
|
method: 'POST',
|
|
@@ -210,6 +200,8 @@ export async function sendAgentMessage({
|
|
|
210
200
|
reply_to_message_id: replyToMessageId ?? null,
|
|
211
201
|
runtime_host_id: runtimeHostId ?? null,
|
|
212
202
|
visibility: visibility || null,
|
|
203
|
+
media_asset_ids: Array.isArray(mediaAssetIds) && mediaAssetIds.length > 0 ? mediaAssetIds : undefined,
|
|
204
|
+
metadata: metadata ?? undefined,
|
|
213
205
|
}),
|
|
214
206
|
});
|
|
215
207
|
return data || null;
|
|
@@ -436,6 +428,20 @@ export async function uploadAgentAttachment({
|
|
|
436
428
|
});
|
|
437
429
|
}
|
|
438
430
|
|
|
431
|
+
export async function uploadAgentAvatar({
|
|
432
|
+
actingAgentId, filename, contentType, dataBase64,
|
|
433
|
+
}) {
|
|
434
|
+
return apiFetch('/api/agent/profile/avatar', {
|
|
435
|
+
method: 'POST',
|
|
436
|
+
body: JSON.stringify({
|
|
437
|
+
acting_as_agent_id: actingAgentId,
|
|
438
|
+
filename,
|
|
439
|
+
content_type: contentType,
|
|
440
|
+
data_base64: dataBase64,
|
|
441
|
+
}),
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
|
|
439
445
|
export async function viewAgentAttachment({ actingAgentId, assetId }) {
|
|
440
446
|
const params = new URLSearchParams();
|
|
441
447
|
params.set('acting_as_agent_id', actingAgentId);
|
|
@@ -480,20 +486,222 @@ export async function removeAgentGroupMember({
|
|
|
480
486
|
);
|
|
481
487
|
}
|
|
482
488
|
|
|
483
|
-
// ──
|
|
489
|
+
// ── Workstreams (managed groups) ──
|
|
484
490
|
|
|
485
|
-
export async function
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
491
|
+
export async function createWorkstream({
|
|
492
|
+
actingAgentId, name, description, charter, memberAgentIds,
|
|
493
|
+
}) {
|
|
494
|
+
return apiFetch('/api/agent/workstreams', {
|
|
495
|
+
method: 'POST',
|
|
496
|
+
body: JSON.stringify({
|
|
497
|
+
acting_as_agent_id: actingAgentId,
|
|
498
|
+
name,
|
|
499
|
+
description: description ?? null,
|
|
500
|
+
charter: charter ?? null,
|
|
501
|
+
member_agent_ids: memberAgentIds || [],
|
|
502
|
+
}),
|
|
503
|
+
});
|
|
504
|
+
}
|
|
490
505
|
|
|
491
|
-
|
|
506
|
+
export async function deleteWorkstream({ actingAgentId, conversationId }) {
|
|
507
|
+
return apiFetch(
|
|
508
|
+
`/api/agent/workstreams/${encodeURIComponent(conversationId)}`,
|
|
509
|
+
{
|
|
510
|
+
method: 'DELETE',
|
|
511
|
+
body: JSON.stringify({ acting_as_agent_id: actingAgentId }),
|
|
512
|
+
},
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
export async function listWorkstreams({ actingAgentId }) {
|
|
517
|
+
const params = new URLSearchParams();
|
|
518
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
519
|
+
const { data } = await apiFetch(`/api/agent/workstreams?${params}`);
|
|
520
|
+
return data || [];
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// ── Agents ──
|
|
524
|
+
|
|
525
|
+
export async function listAgentSlots({ actingAgentId }) {
|
|
526
|
+
const params = new URLSearchParams();
|
|
527
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
528
|
+
const { data } = await apiFetch(`/api/agent/agents?${params}`);
|
|
529
|
+
return data || [];
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export async function createAgentSlot({
|
|
533
|
+
actingAgentId, name, runtime, description, displayName, model,
|
|
534
|
+
}) {
|
|
535
|
+
return apiFetch('/api/agent/agents', {
|
|
492
536
|
method: 'POST',
|
|
493
|
-
body:
|
|
494
|
-
|
|
537
|
+
body: JSON.stringify({
|
|
538
|
+
acting_as_agent_id: actingAgentId,
|
|
539
|
+
name,
|
|
540
|
+
runtime,
|
|
541
|
+
description: description ?? null,
|
|
542
|
+
display_name: displayName ?? null,
|
|
543
|
+
model: model ?? null,
|
|
544
|
+
}),
|
|
495
545
|
});
|
|
496
|
-
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
export async function archiveAgentSlot({ actingAgentId, agentId }) {
|
|
549
|
+
return apiFetch(
|
|
550
|
+
`/api/agent/agents/${encodeURIComponent(agentId)}`,
|
|
551
|
+
{
|
|
552
|
+
method: 'DELETE',
|
|
553
|
+
body: JSON.stringify({ acting_as_agent_id: actingAgentId }),
|
|
554
|
+
},
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// ── Services ──
|
|
559
|
+
|
|
560
|
+
export async function createService({
|
|
561
|
+
actingAgentId, name, description, contractSchema, endpointConfig,
|
|
562
|
+
}) {
|
|
563
|
+
return apiFetch('/api/agent/services', {
|
|
564
|
+
method: 'POST',
|
|
565
|
+
body: JSON.stringify({
|
|
566
|
+
acting_as_agent_id: actingAgentId,
|
|
567
|
+
name,
|
|
568
|
+
description: description ?? null,
|
|
569
|
+
contract_schema: contractSchema ?? null,
|
|
570
|
+
endpoint_config: endpointConfig,
|
|
571
|
+
}),
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
export async function updateService({ actingAgentId, serviceId, ...patch }) {
|
|
576
|
+
return apiFetch(
|
|
577
|
+
`/api/agent/services/${encodeURIComponent(serviceId)}`,
|
|
578
|
+
{
|
|
579
|
+
method: 'PATCH',
|
|
580
|
+
body: JSON.stringify({ acting_as_agent_id: actingAgentId, ...patch }),
|
|
581
|
+
},
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
export async function deleteService({ actingAgentId, serviceId }) {
|
|
586
|
+
return apiFetch(
|
|
587
|
+
`/api/agent/services/${encodeURIComponent(serviceId)}`,
|
|
588
|
+
{
|
|
589
|
+
method: 'DELETE',
|
|
590
|
+
body: JSON.stringify({ acting_as_agent_id: actingAgentId }),
|
|
591
|
+
},
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
export async function listServices({ actingAgentId }) {
|
|
596
|
+
const params = new URLSearchParams();
|
|
597
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
598
|
+
const { data } = await apiFetch(`/api/agent/services?${params}`);
|
|
599
|
+
return data || [];
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
export async function getServiceInfo({ actingAgentId, name }) {
|
|
603
|
+
const params = new URLSearchParams();
|
|
604
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
605
|
+
return apiFetch(
|
|
606
|
+
`/api/agent/services/${encodeURIComponent(name)}/info?${params}`,
|
|
607
|
+
);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
export async function callService({ actingAgentId, name, input }) {
|
|
611
|
+
return apiFetch(
|
|
612
|
+
`/api/agent/services/${encodeURIComponent(name)}/call`,
|
|
613
|
+
{
|
|
614
|
+
method: 'POST',
|
|
615
|
+
body: JSON.stringify({ acting_as_agent_id: actingAgentId, input }),
|
|
616
|
+
},
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// ── Briefings ──
|
|
621
|
+
|
|
622
|
+
export async function getBriefing({actingAgentId, briefingId}) {
|
|
623
|
+
const params = new URLSearchParams();
|
|
624
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
625
|
+
return apiFetch(`/api/agent/briefings/${encodeURIComponent(briefingId)}?${params}`);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
export async function publishBriefing({actingAgentId, bodyText, attachmentAssetId, currentConversationId, responseMode}) {
|
|
629
|
+
const body = { acting_as_agent_id: actingAgentId };
|
|
630
|
+
if (bodyText != null) body.body_text = bodyText;
|
|
631
|
+
if (attachmentAssetId != null) body.attachment_asset_id = attachmentAssetId;
|
|
632
|
+
if (currentConversationId != null) body.current_conversation_id = currentConversationId;
|
|
633
|
+
if (responseMode != null) body.response_mode = responseMode;
|
|
634
|
+
return apiFetch('/api/agent/briefings', {
|
|
635
|
+
method: 'POST',
|
|
636
|
+
body: JSON.stringify(body),
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// ── Credentials (slot creation + daemon sync) ──
|
|
641
|
+
|
|
642
|
+
export async function fetchCredentials() {
|
|
643
|
+
return apiFetch('/api/agent/credentials', { method: 'GET' });
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
export async function requestCredential({
|
|
647
|
+
actingAgentId, name, description, workstreamId,
|
|
648
|
+
}) {
|
|
649
|
+
return apiFetch('/api/agent/credentials', {
|
|
650
|
+
method: 'POST',
|
|
651
|
+
body: JSON.stringify({
|
|
652
|
+
acting_as_agent_id: actingAgentId,
|
|
653
|
+
name,
|
|
654
|
+
description: description ?? null,
|
|
655
|
+
workstream_id: workstreamId ?? null,
|
|
656
|
+
}),
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// ── Workstream dashboard ──
|
|
661
|
+
|
|
662
|
+
export async function setWorkstreamDashboard({
|
|
663
|
+
actingAgentId, conversationId, dataJson, htmlTemplate,
|
|
664
|
+
}) {
|
|
665
|
+
const body = { acting_as_agent_id: actingAgentId };
|
|
666
|
+
// Distinguish "omit" from "set to null" — only include keys the caller
|
|
667
|
+
// explicitly passed (including null clears the field).
|
|
668
|
+
if (dataJson !== undefined) body.data_json = dataJson;
|
|
669
|
+
if (htmlTemplate !== undefined) body.html_template = htmlTemplate;
|
|
670
|
+
return apiFetch(
|
|
671
|
+
`/api/agent/workstreams/${encodeURIComponent(conversationId)}/dashboard`,
|
|
672
|
+
{ method: 'POST', body: JSON.stringify(body) },
|
|
673
|
+
);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
export async function getWorkstreamDashboard({ actingAgentId, conversationId }) {
|
|
677
|
+
const params = new URLSearchParams();
|
|
678
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
679
|
+
return apiFetch(
|
|
680
|
+
`/api/agent/workstreams/${encodeURIComponent(conversationId)}/dashboard?${params}`,
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// ── Workstream charter ──
|
|
685
|
+
|
|
686
|
+
export async function getWorkstreamCharter({ actingAgentId, conversationId }) {
|
|
687
|
+
const params = new URLSearchParams();
|
|
688
|
+
params.set('acting_as_agent_id', actingAgentId);
|
|
689
|
+
return apiFetch(
|
|
690
|
+
`/api/agent/workstreams/${encodeURIComponent(conversationId)}/charter?${params}`,
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
export async function setWorkstreamCharter({ actingAgentId, conversationId, charter }) {
|
|
695
|
+
return apiFetch(
|
|
696
|
+
`/api/agent/workstreams/${encodeURIComponent(conversationId)}/charter`,
|
|
697
|
+
{
|
|
698
|
+
method: 'POST',
|
|
699
|
+
body: JSON.stringify({
|
|
700
|
+
acting_as_agent_id: actingAgentId,
|
|
701
|
+
charter: charter ?? null,
|
|
702
|
+
}),
|
|
703
|
+
},
|
|
704
|
+
);
|
|
497
705
|
}
|
|
498
706
|
|
|
499
707
|
// ── Channel event pipe ──
|
|
@@ -6,7 +6,20 @@
|
|
|
6
6
|
* using the connector-specific env name.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { AF_CONFIG_PATH, persistConfig, TICLAWK_CONNECTOR_API_KEY } from '../../core/config.mjs';
|
|
9
|
+
import { AF_CONFIG_PATH, loadPersistentConfig, persistConfig, TICLAWK_CONNECTOR_API_KEY } from '../../core/config.mjs';
|
|
10
|
+
|
|
11
|
+
export const TICLAWK_CREDENTIAL_NAMES = 'TICLAWK_CREDENTIAL_NAMES';
|
|
12
|
+
|
|
13
|
+
function isRuntimeCredentialName(value) {
|
|
14
|
+
return /^[A-Z][A-Z0-9_]*$/.test(String(value || '').trim());
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function parseCredentialNames(value) {
|
|
18
|
+
return String(value || '')
|
|
19
|
+
.split(',')
|
|
20
|
+
.map((name) => name.trim())
|
|
21
|
+
.filter(isRuntimeCredentialName);
|
|
22
|
+
}
|
|
10
23
|
|
|
11
24
|
export function persistApiCredential(apiKey) {
|
|
12
25
|
if (!apiKey || !apiKey.startsWith('tk_')) return;
|
|
@@ -19,3 +32,30 @@ export function persistApiCredential(apiKey) {
|
|
|
19
32
|
delete process.env.TICLAWK_SETUP_CODE;
|
|
20
33
|
console.log(`[connect] saved ${TICLAWK_CONNECTOR_API_KEY} to ${AF_CONFIG_PATH}`);
|
|
21
34
|
}
|
|
35
|
+
|
|
36
|
+
export function persistRuntimeCredentials(credentials = []) {
|
|
37
|
+
const current = loadPersistentConfig();
|
|
38
|
+
const previousNames = new Set(parseCredentialNames(current[TICLAWK_CREDENTIAL_NAMES]));
|
|
39
|
+
const nextNames = [];
|
|
40
|
+
const updates = {};
|
|
41
|
+
|
|
42
|
+
for (const credential of Array.isArray(credentials) ? credentials : []) {
|
|
43
|
+
const name = String(credential?.name || '').trim();
|
|
44
|
+
const value = typeof credential?.value === 'string' ? credential.value : '';
|
|
45
|
+
if (!isRuntimeCredentialName(name) || !value) continue;
|
|
46
|
+
updates[name] = value;
|
|
47
|
+
nextNames.push(name);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const nextNameSet = new Set(nextNames);
|
|
51
|
+
for (const name of previousNames) {
|
|
52
|
+
if (!nextNameSet.has(name)) updates[name] = '';
|
|
53
|
+
}
|
|
54
|
+
updates[TICLAWK_CREDENTIAL_NAMES] = nextNames.join(',');
|
|
55
|
+
|
|
56
|
+
persistConfig(updates);
|
|
57
|
+
return {
|
|
58
|
+
saved: nextNames.length,
|
|
59
|
+
removed: [...previousNames].filter((name) => !nextNameSet.has(name)).length,
|
|
60
|
+
};
|
|
61
|
+
}
|