@kafca/agentdock 0.1.7

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.
Files changed (79) hide show
  1. package/README.md +70 -0
  2. package/bin/agentdock.mjs +275 -0
  3. package/build/icon.png +0 -0
  4. package/dist/renderer/assets/index-BaNpzC6d.js +482 -0
  5. package/dist/renderer/assets/index-CLWJyO0E.css +11 -0
  6. package/dist/renderer/favicon.svg +19 -0
  7. package/dist/renderer/index.html +14 -0
  8. package/dist/renderer/logo-options.svg +153 -0
  9. package/dist-electron/electron/knowledge-skill-script.test.js +125 -0
  10. package/dist-electron/electron/lac-cli.test.js +221 -0
  11. package/dist-electron/electron/local-core-refactor.test.js +1075 -0
  12. package/dist-electron/electron/main.js +163 -0
  13. package/dist-electron/electron/plugin-kernel.test.js +534 -0
  14. package/dist-electron/electron/preload.js +2 -0
  15. package/dist-electron/package.json +3 -0
  16. package/dist-electron/packages/contracts/src/index.js +18 -0
  17. package/dist-electron/packages/contracts/src/local-core.js +2 -0
  18. package/dist-electron/packages/core-sdk/src/index.js +406 -0
  19. package/dist-electron/packages/knowledge-api/src/ai-vector-provider.js +388 -0
  20. package/dist-electron/packages/knowledge-api/src/index.js +146 -0
  21. package/dist-electron/packages/knowledge-api/src/sqlite-store.js +467 -0
  22. package/dist-electron/packages/knowledge-api/src/thread-knowledge-store.js +21 -0
  23. package/dist-electron/packages/knowledge-api/test/ai-vector-provider.test.js +412 -0
  24. package/dist-electron/packages/plugin-sdk/src/index.js +2 -0
  25. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +369 -0
  26. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-response-processor.js +110 -0
  27. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +171 -0
  28. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-store.js +635 -0
  29. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-transport.js +190 -0
  30. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +244 -0
  31. package/dist-electron/services/local-ai-core/src/acp/workspace-acp-permissions.js +52 -0
  32. package/dist-electron/services/local-ai-core/src/cli/lac.js +290 -0
  33. package/dist-electron/services/local-ai-core/src/gateway/local-core-lark-gateway.js +976 -0
  34. package/dist-electron/services/local-ai-core/src/gateway/local-core-weixin-gateway.js +1143 -0
  35. package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +291 -0
  36. package/dist-electron/services/local-ai-core/src/kernel/capability-registry.js +67 -0
  37. package/dist-electron/services/local-ai-core/src/kernel/diagnostics.js +27 -0
  38. package/dist-electron/services/local-ai-core/src/kernel/event-bus.js +27 -0
  39. package/dist-electron/services/local-ai-core/src/kernel/lifecycle-manager.js +85 -0
  40. package/dist-electron/services/local-ai-core/src/kernel/plugin-registry.js +60 -0
  41. package/dist-electron/services/local-ai-core/src/plugins/builtin/agent-localcore-acp-plugin.js +114 -0
  42. package/dist-electron/services/local-ai-core/src/plugins/builtin/channel-lark-plugin.js +59 -0
  43. package/dist-electron/services/local-ai-core/src/plugins/builtin/channel-weixin-plugin.js +56 -0
  44. package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-ai-vector-plugin.js +7 -0
  45. package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-noop-plugin.js +7 -0
  46. package/dist-electron/services/local-ai-core/src/plugins/builtin/runtime-capabilities-plugin.js +62 -0
  47. package/dist-electron/services/local-ai-core/src/plugins/builtin/scheduler-cron-plugin.js +49 -0
  48. package/dist-electron/services/local-ai-core/src/plugins/builtin/scheduler-lark-plugin.js +38 -0
  49. package/dist-electron/services/local-ai-core/src/plugins/builtin/scheduler-weixin-plugin.js +38 -0
  50. package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +230 -0
  51. package/dist-electron/services/local-ai-core/src/router/workspace-router-types.js +2 -0
  52. package/dist-electron/services/local-ai-core/src/router/workspace-router.js +389 -0
  53. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +315 -0
  54. package/dist-electron/services/local-ai-core/src/runtime/local-core-runtime-state.js +282 -0
  55. package/dist-electron/services/local-ai-core/src/runtime/server.js +465 -0
  56. package/dist-electron/services/local-ai-core/src/runtime/standalone.js +38 -0
  57. package/dist-electron/services/local-ai-core/src/scheduler/adapters.js +2 -0
  58. package/dist-electron/services/local-ai-core/src/scheduler/cron-command-detector.js +70 -0
  59. package/dist-electron/services/local-ai-core/src/scheduler/cron.js +53 -0
  60. package/dist-electron/services/local-ai-core/src/scheduler/execution-policy.js +2 -0
  61. package/dist-electron/services/local-ai-core/src/scheduler/lark-execution-policies.js +66 -0
  62. package/dist-electron/services/local-ai-core/src/scheduler/lark-schedule-adapter.js +77 -0
  63. package/dist-electron/services/local-ai-core/src/scheduler/scheduled-conversation-executor.js +46 -0
  64. package/dist-electron/services/local-ai-core/src/scheduler/scheduler-run-lifecycle.js +64 -0
  65. package/dist-electron/services/local-ai-core/src/scheduler/scheduler-service.js +133 -0
  66. package/dist-electron/services/local-ai-core/src/scheduler/weixin-execution-policies.js +66 -0
  67. package/dist-electron/services/local-ai-core/src/scheduler/weixin-schedule-adapter.js +78 -0
  68. package/dist-electron/services/local-ai-core/src/thread/workspace-thread-id.js +17 -0
  69. package/dist-electron/services/local-ai-core/src/thread/workspace-thread-mappers.js +43 -0
  70. package/dist-electron/shared/desktop.js +195 -0
  71. package/dist-electron/src/api/client.js +73 -0
  72. package/dist-electron/src/api/sessions.js +21 -0
  73. package/dist-electron/src/lib/session-utils.js +51 -0
  74. package/dist-electron/src/pages/Threads/thread-chat-model.js +246 -0
  75. package/dist-electron/src/pages/Threads/thread-chat-model.test.js +76 -0
  76. package/dist-electron/src/pages/Threads/thread-chat-permission.js +26 -0
  77. package/dist-electron/src/pages/Threads/thread-chat-permission.test.js +102 -0
  78. package/dist-electron/src/pages/Threads/thread-chat-task-state.js +65 -0
  79. package/package.json +146 -0
@@ -0,0 +1,290 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runCli = runCli;
7
+ const node_process_1 = __importDefault(require("node:process"));
8
+ const DEFAULT_BASE_URL = 'http://127.0.0.1:9831/api/local/v1';
9
+ async function runCli(argv, env = node_process_1.default.env, io = node_process_1.default) {
10
+ try {
11
+ const { positionals, flags } = parseArgs(argv);
12
+ const [domain = '', action = '', maybeId = ''] = positionals;
13
+ if (domain !== 'scheduler') {
14
+ printUsage(io.stderr);
15
+ return 2;
16
+ }
17
+ const json = getBooleanFlag(flags, 'json', false);
18
+ switch (action) {
19
+ case 'add':
20
+ return await handleAdd(flags, env, io, json);
21
+ case 'list':
22
+ return await handleList(flags, env, io, json);
23
+ case 'info':
24
+ return await handleInfo(maybeId, flags, env, io, json);
25
+ case 'edit':
26
+ return await handleEdit(maybeId, flags, env, io, json);
27
+ case 'del':
28
+ case 'delete':
29
+ return await handleDelete(maybeId, flags, env, io, json);
30
+ case 'run':
31
+ return await handleRun(maybeId, flags, env, io, json);
32
+ default:
33
+ printUsage(io.stderr);
34
+ return 2;
35
+ }
36
+ }
37
+ catch (error) {
38
+ io.stderr.write(`${formatError(error)}\n`);
39
+ return 1;
40
+ }
41
+ }
42
+ async function handleAdd(flags, env, io, json) {
43
+ const cronExpr = getRequiredFlag(flags, 'cron');
44
+ const promptTemplate = getRequiredFlag(flags, 'message');
45
+ const description = getRequiredFlag(flags, 'desc');
46
+ const executionMode = getExecutionMode(flags);
47
+ const context = resolveContext(flags, env);
48
+ if (!context.workspaceId || !context.threadId) {
49
+ throw new Error('scheduler add requires a current workspace/thread context.');
50
+ }
51
+ if (context.platform !== 'lark' || !['channel.chat', 'lark_chat'].includes(context.routeType) || !context.chatId || !context.platformUserId) {
52
+ throw new Error('scheduler add requires a bound Lark route. Missing LOCAL_AI_CHAT_ID or LOCAL_AI_PLATFORM_USER_ID.');
53
+ }
54
+ const job = await request(context.baseUrl, 'POST', '/scheduler/jobs', {
55
+ workspaceId: context.workspaceId,
56
+ platform: 'lark',
57
+ route: {
58
+ type: 'channel.chat',
59
+ channelId: context.chatId,
60
+ participantId: context.platformUserId,
61
+ threadId: context.threadId,
62
+ },
63
+ executionMode,
64
+ triggerType: 'cron',
65
+ cronExpr,
66
+ promptTemplate,
67
+ description,
68
+ enabled: true,
69
+ });
70
+ print(json, io.stdout, job, [
71
+ `Created scheduler job ${job.id}`,
72
+ `Schedule: ${job.cronExpr || ''}`,
73
+ `Execution mode: ${job.executionMode}`,
74
+ `Description: ${job.description}`,
75
+ ].join('\n'));
76
+ return 0;
77
+ }
78
+ async function handleList(flags, env, io, json) {
79
+ const context = resolveContext(flags, env);
80
+ const workspaceId = getFlag(flags, 'workspace') || context.workspaceId;
81
+ const threadId = flags.has('thread')
82
+ ? normalizeMaybeBooleanFlag(getFlag(flags, 'thread')) || context.threadId
83
+ : '';
84
+ const suffix = workspaceId ? `?workspace_id=${encodeURIComponent(workspaceId)}` : '';
85
+ const response = await request(context.baseUrl, 'GET', `/scheduler/jobs${suffix}`);
86
+ const jobs = threadId
87
+ ? response.jobs.filter((job) => job.route.threadId === threadId)
88
+ : response.jobs;
89
+ print(json, io.stdout, { jobs }, jobs.length === 0 ? 'No scheduler jobs.' : jobs.map(formatJobLine).join('\n'));
90
+ return 0;
91
+ }
92
+ async function handleInfo(jobId, flags, env, io, json) {
93
+ if (!jobId) {
94
+ throw new Error('scheduler info requires a job id.');
95
+ }
96
+ const context = resolveContext(flags, env);
97
+ const job = await request(context.baseUrl, 'GET', `/scheduler/jobs/${encodeURIComponent(jobId)}`);
98
+ const runs = await request(context.baseUrl, 'GET', `/scheduler/jobs/${encodeURIComponent(jobId)}/runs`);
99
+ print(json, io.stdout, { job, runs: runs.runs }, formatJobDetails(job, runs.runs[0]));
100
+ return 0;
101
+ }
102
+ async function handleEdit(jobId, flags, env, io, json) {
103
+ if (!jobId) {
104
+ throw new Error('scheduler edit requires a job id.');
105
+ }
106
+ const input = {};
107
+ const cronExpr = getFlag(flags, 'cron');
108
+ const promptTemplate = getFlag(flags, 'message');
109
+ const description = getFlag(flags, 'desc');
110
+ const enabled = getOptionalBooleanFlag(flags, 'enabled');
111
+ const executionMode = getFlag(flags, 'execution-mode');
112
+ if (cronExpr) {
113
+ input.cronExpr = cronExpr;
114
+ }
115
+ if (typeof promptTemplate === 'string') {
116
+ input.promptTemplate = promptTemplate;
117
+ }
118
+ if (typeof description === 'string') {
119
+ input.description = description;
120
+ }
121
+ if (typeof enabled === 'boolean') {
122
+ input.enabled = enabled;
123
+ }
124
+ if (executionMode) {
125
+ input.executionMode = parseExecutionMode(executionMode);
126
+ }
127
+ if (Object.keys(input).length === 0) {
128
+ throw new Error('scheduler edit requires at least one editable field.');
129
+ }
130
+ const context = resolveContext(flags, env);
131
+ const job = await request(context.baseUrl, 'PATCH', `/scheduler/jobs/${encodeURIComponent(jobId)}`, input);
132
+ print(json, io.stdout, job, `Updated scheduler job ${job.id}`);
133
+ return 0;
134
+ }
135
+ async function handleDelete(jobId, flags, env, io, json) {
136
+ if (!jobId) {
137
+ throw new Error('scheduler del requires a job id.');
138
+ }
139
+ const context = resolveContext(flags, env);
140
+ const result = await request(context.baseUrl, 'DELETE', `/scheduler/jobs/${encodeURIComponent(jobId)}`);
141
+ print(json, io.stdout, result, `Deleted scheduler job ${jobId}`);
142
+ return 0;
143
+ }
144
+ async function handleRun(jobId, flags, env, io, json) {
145
+ if (!jobId) {
146
+ throw new Error('scheduler run requires a job id.');
147
+ }
148
+ const context = resolveContext(flags, env);
149
+ const run = await request(context.baseUrl, 'POST', `/scheduler/jobs/${encodeURIComponent(jobId)}/run`);
150
+ print(json, io.stdout, run, `Triggered scheduler job ${jobId}: ${run.status}`);
151
+ return 0;
152
+ }
153
+ async function request(baseUrl, method, path, body) {
154
+ let response;
155
+ try {
156
+ response = await fetch(`${baseUrl}${path}`, {
157
+ method,
158
+ headers: {
159
+ 'Content-Type': 'application/json',
160
+ },
161
+ body: body ? JSON.stringify(body) : undefined,
162
+ });
163
+ }
164
+ catch (error) {
165
+ throw new Error(`Local AI Core is unavailable at ${baseUrl}: ${formatError(error)}`);
166
+ }
167
+ const payload = await response.json();
168
+ if (!response.ok || !payload.ok) {
169
+ throw new Error(payload.error || `Local AI Core request failed: ${response.status}`);
170
+ }
171
+ return payload.data;
172
+ }
173
+ function resolveContext(flags, env) {
174
+ const platform = getFlag(flags, 'platform') || String(env.LOCAL_AI_PLATFORM || '');
175
+ const chatId = getFlag(flags, 'chat-id') || String(env.LOCAL_AI_CHAT_ID || '');
176
+ const platformUserId = getFlag(flags, 'platform-user-id') || String(env.LOCAL_AI_PLATFORM_USER_ID || '');
177
+ return {
178
+ baseUrl: getFlag(flags, 'base-url') || String(env.LOCAL_AI_CORE_BASE || DEFAULT_BASE_URL),
179
+ workspaceId: getFlag(flags, 'workspace') || String(env.LOCAL_AI_WORKSPACE_ID || ''),
180
+ threadId: normalizeMaybeBooleanFlag(getFlag(flags, 'thread')) || String(env.LOCAL_AI_THREAD_ID || ''),
181
+ platform,
182
+ routeType: String(env.LOCAL_AI_ROUTE_TYPE || '') || (platform === 'lark' && chatId && platformUserId ? 'channel.chat' : ''),
183
+ chatId,
184
+ platformUserId,
185
+ };
186
+ }
187
+ function parseArgs(argv) {
188
+ const positionals = [];
189
+ const flags = new Map();
190
+ for (let i = 0; i < argv.length; i += 1) {
191
+ const part = argv[i];
192
+ if (!part.startsWith('--')) {
193
+ positionals.push(part);
194
+ continue;
195
+ }
196
+ const key = part.slice(2);
197
+ const next = argv[i + 1];
198
+ if (!next || next.startsWith('--')) {
199
+ flags.set(key, ['true']);
200
+ continue;
201
+ }
202
+ flags.set(key, [next]);
203
+ i += 1;
204
+ }
205
+ return { positionals, flags };
206
+ }
207
+ function getFlag(flags, name) {
208
+ return flags.get(name)?.[0] || '';
209
+ }
210
+ function getRequiredFlag(flags, name) {
211
+ const value = getFlag(flags, name);
212
+ if (!value) {
213
+ throw new Error(`Missing required flag --${name}`);
214
+ }
215
+ return value;
216
+ }
217
+ function getBooleanFlag(flags, name, defaultValue) {
218
+ const value = getFlag(flags, name);
219
+ if (!value) {
220
+ return defaultValue;
221
+ }
222
+ return value !== 'false';
223
+ }
224
+ function getOptionalBooleanFlag(flags, name) {
225
+ const value = getFlag(flags, name);
226
+ if (!value) {
227
+ return undefined;
228
+ }
229
+ if (value === 'true') {
230
+ return true;
231
+ }
232
+ if (value === 'false') {
233
+ return false;
234
+ }
235
+ throw new Error(`Flag --${name} must be true or false`);
236
+ }
237
+ function normalizeMaybeBooleanFlag(value) {
238
+ return value === 'true' ? '' : value;
239
+ }
240
+ function getExecutionMode(flags) {
241
+ return parseExecutionMode(getFlag(flags, 'execution-mode') || 'same-thread');
242
+ }
243
+ function parseExecutionMode(value) {
244
+ if (value === 'same-thread' || value === 'side-thread') {
245
+ return value;
246
+ }
247
+ throw new Error('Flag --execution-mode must be same-thread or side-thread');
248
+ }
249
+ function print(asJson, output, payload, text) {
250
+ output.write(asJson ? `${JSON.stringify(payload, null, 2)}\n` : `${text}\n`);
251
+ }
252
+ function printUsage(output) {
253
+ output.write([
254
+ 'Usage:',
255
+ ' lac scheduler add --cron "<expr>" --message "<text>" --desc "<label>" [--execution-mode same-thread|side-thread] [--json]',
256
+ ' lac scheduler list [--workspace <id>] [--thread [<id>]] [--json]',
257
+ ' lac scheduler info <job-id> [--json]',
258
+ ' lac scheduler edit <job-id> [--cron "<expr>"] [--message "<text>"] [--desc "<label>"] [--enabled true|false] [--execution-mode same-thread|side-thread] [--json]',
259
+ ' lac scheduler del <job-id> [--json]',
260
+ ' lac scheduler run <job-id> [--json]',
261
+ ].join('\n') + '\n');
262
+ }
263
+ function formatJobLine(job) {
264
+ const schedule = job.triggerType === 'cron' ? job.cronExpr || '' : job.runAt || '';
265
+ return `${job.id} | ${job.enabled ? 'enabled' : 'disabled'} | ${job.executionMode} | ${schedule} | ${job.description}`;
266
+ }
267
+ function formatJobDetails(job, latestRun) {
268
+ return [
269
+ `Job: ${job.id}`,
270
+ `Workspace: ${job.workspaceId}`,
271
+ `Platform: ${job.platform}`,
272
+ `Thread: ${job.route.threadId || ''}`,
273
+ `Execution mode: ${job.executionMode}`,
274
+ `Schedule: ${job.triggerType === 'cron' ? job.cronExpr || '' : job.runAt || ''}`,
275
+ `Enabled: ${job.enabled ? 'true' : 'false'}`,
276
+ `Description: ${job.description}`,
277
+ `Message: ${job.promptTemplate}`,
278
+ latestRun ? `Latest run: ${latestRun.status} @ ${latestRun.triggeredAt}` : 'Latest run: none',
279
+ ].join('\n');
280
+ }
281
+ function formatError(error) {
282
+ return error instanceof Error ? error.message : String(error);
283
+ }
284
+ void (async () => {
285
+ if (require.main !== module) {
286
+ return;
287
+ }
288
+ const exitCode = await runCli(node_process_1.default.argv.slice(2));
289
+ node_process_1.default.exitCode = exitCode;
290
+ })();