@adecore/agents 0.0.1 → 0.17.0-beta.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/LICENSE +110 -0
- package/README.md +33 -0
- package/dist/async.d.ts +2 -0
- package/dist/async.js +31 -0
- package/dist/chat/attachment-store.d.ts +10 -0
- package/dist/chat/attachment-store.js +93 -0
- package/dist/chat/backend.d.ts +214 -0
- package/dist/chat/backend.js +1 -0
- package/dist/chat/background-work.d.ts +8 -0
- package/dist/chat/background-work.js +33 -0
- package/dist/chat/bookmark-store.d.ts +25 -0
- package/dist/chat/bookmark-store.js +141 -0
- package/dist/chat/chat-core.d.ts +311 -0
- package/dist/chat/chat-core.js +1025 -0
- package/dist/chat/chat-log.d.ts +33 -0
- package/dist/chat/chat-log.js +163 -0
- package/dist/chat/chat-process.d.ts +46 -0
- package/dist/chat/chat-process.js +190 -0
- package/dist/chat/chat-session.d.ts +209 -0
- package/dist/chat/chat-session.js +1511 -0
- package/dist/chat/chat-store.d.ts +37 -0
- package/dist/chat/chat-store.js +202 -0
- package/dist/chat/chat-title.d.ts +10 -0
- package/dist/chat/chat-title.js +74 -0
- package/dist/chat/claude-backend.d.ts +35 -0
- package/dist/chat/claude-backend.js +214 -0
- package/dist/chat/claude-protocol.d.ts +41 -0
- package/dist/chat/claude-protocol.js +642 -0
- package/dist/chat/claude-title.d.ts +11 -0
- package/dist/chat/claude-title.js +97 -0
- package/dist/chat/claude-transcript.d.ts +28 -0
- package/dist/chat/claude-transcript.js +211 -0
- package/dist/chat/codex-backend.d.ts +51 -0
- package/dist/chat/codex-backend.js +364 -0
- package/dist/chat/codex-protocol.d.ts +56 -0
- package/dist/chat/codex-protocol.js +767 -0
- package/dist/chat/codex-thread.d.ts +32 -0
- package/dist/chat/codex-thread.js +131 -0
- package/dist/chat/codex-transport.d.ts +42 -0
- package/dist/chat/codex-transport.js +188 -0
- package/dist/chat/composer-preferences.d.ts +15 -0
- package/dist/chat/composer-preferences.js +46 -0
- package/dist/chat/context-breakdown.d.ts +2 -0
- package/dist/chat/context-breakdown.js +74 -0
- package/dist/chat/delta-coalescer.d.ts +12 -0
- package/dist/chat/delta-coalescer.js +55 -0
- package/dist/chat/errors.d.ts +4 -0
- package/dist/chat/errors.js +4 -0
- package/dist/chat/fake-claude.d.ts +3 -0
- package/dist/chat/fake-claude.js +982 -0
- package/dist/chat/fake-cli.d.ts +25 -0
- package/dist/chat/fake-cli.js +157 -0
- package/dist/chat/fake-codex.d.ts +10 -0
- package/dist/chat/fake-codex.js +502 -0
- package/dist/chat/fixtures/claude-2.1.285-auto-fallback.json +24 -0
- package/dist/chat/fixtures/claude-2.1.285-native-children.json +6600 -0
- package/dist/chat/fixtures/claude-2.1.285-resume-direct-compact.json +202 -0
- package/dist/chat/fixtures/claude-2.1.285-resume-task-notification.json +57 -0
- package/dist/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a4c2e8f10b3d5a7e9.jsonl +10 -0
- package/dist/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a4c2e8f10b3d5a7e9.meta.json +1 -0
- package/dist/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a9b8c7d6e5f4a3b21.jsonl +2 -0
- package/dist/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a9b8c7d6e5f4a3b21.meta.json +1 -0
- package/dist/chat/fixtures/codex-0.159.2-native-approval.json +119 -0
- package/dist/chat/fixtures/codex-0.159.2-native-file-approval.json +136 -0
- package/dist/chat/fixtures/codex-0.159.2-native-interacted.json +220 -0
- package/dist/chat/fixtures/codex-0.159.2-usage-windows.json +74 -0
- package/dist/chat/input.d.ts +19 -0
- package/dist/chat/input.js +71 -0
- package/dist/chat/limit-resume.d.ts +11 -0
- package/dist/chat/limit-resume.js +68 -0
- package/dist/chat/projector.d.ts +60 -0
- package/dist/chat/projector.js +860 -0
- package/dist/chat/request-summary.d.ts +3 -0
- package/dist/chat/request-summary.js +143 -0
- package/dist/chat/subagent-projection.d.ts +8 -0
- package/dist/chat/subagent-projection.js +40 -0
- package/dist/chat/subagent-reader.d.ts +66 -0
- package/dist/chat/subagent-reader.js +396 -0
- package/dist/chat/subagent-settlement.d.ts +6 -0
- package/dist/chat/subagent-settlement.js +103 -0
- package/dist/chat/thread.d.ts +30 -0
- package/dist/chat/thread.js +147 -0
- package/dist/chat/wake-chat.d.ts +20 -0
- package/dist/chat/wake-chat.js +27 -0
- package/dist/client-sinks.d.ts +9 -0
- package/dist/client-sinks.js +34 -0
- package/dist/coded-error.d.ts +5 -0
- package/dist/coded-error.js +17 -0
- package/dist/context/argv.d.ts +11 -0
- package/dist/context/argv.js +58 -0
- package/dist/context/refusal.d.ts +9 -0
- package/dist/context/refusal.js +38 -0
- package/dist/context/verb.d.ts +85 -0
- package/dist/context/verb.js +233 -0
- package/dist/error-text.d.ts +5 -0
- package/dist/error-text.js +24 -0
- package/dist/events.d.ts +12 -0
- package/dist/events.js +1 -0
- package/dist/fs.d.ts +9 -0
- package/dist/fs.js +107 -0
- package/dist/host/agent-host.d.ts +28 -0
- package/dist/host/agent-host.js +105 -0
- package/dist/host/environment.d.ts +7 -0
- package/dist/host/environment.js +22 -0
- package/dist/host/handlers.d.ts +30 -0
- package/dist/host/handlers.js +111 -0
- package/dist/host/memory-port.d.ts +2 -0
- package/dist/host/memory-port.js +25 -0
- package/dist/host/wiring.d.ts +40 -0
- package/dist/host/wiring.js +120 -0
- package/dist/lineage.d.ts +44 -0
- package/dist/lineage.js +134 -0
- package/dist/messages/deliver-message.d.ts +21 -0
- package/dist/messages/deliver-message.js +42 -0
- package/dist/messages/deliver-notice.d.ts +25 -0
- package/dist/messages/deliver-notice.js +75 -0
- package/dist/messages/notice-notes.d.ts +15 -0
- package/dist/messages/notice-notes.js +26 -0
- package/dist/messages/notice-store.d.ts +30 -0
- package/dist/messages/notice-store.js +120 -0
- package/dist/modes.d.ts +11 -0
- package/dist/modes.js +28 -0
- package/dist/outbox/manual-clock.d.ts +10 -0
- package/dist/outbox/manual-clock.js +25 -0
- package/dist/outbox/outbox-worker.d.ts +44 -0
- package/dist/outbox/outbox-worker.js +173 -0
- package/dist/outbox/outbox.d.ts +37 -0
- package/dist/outbox/outbox.js +76 -0
- package/dist/providers/accounts/accounts.d.ts +20 -0
- package/dist/providers/accounts/accounts.js +158 -0
- package/dist/providers/accounts/launch.d.ts +17 -0
- package/dist/providers/accounts/launch.js +30 -0
- package/dist/providers/accounts/service.d.ts +87 -0
- package/dist/providers/accounts/service.js +538 -0
- package/dist/providers/accounts/shadow-home.d.ts +8 -0
- package/dist/providers/accounts/shadow-home.js +70 -0
- package/dist/providers/accounts/status.d.ts +12 -0
- package/dist/providers/accounts/status.js +85 -0
- package/dist/providers/accounts/store.d.ts +14 -0
- package/dist/providers/accounts/store.js +112 -0
- package/dist/providers/accounts/test-accounts.d.ts +12 -0
- package/dist/providers/accounts/test-accounts.js +38 -0
- package/dist/providers/accounts/variables.d.ts +27 -0
- package/dist/providers/accounts/variables.js +94 -0
- package/dist/providers/catalog.d.ts +17 -0
- package/dist/providers/catalog.js +76 -0
- package/dist/providers/claude-models.json +114 -0
- package/dist/providers/claude-provider.d.ts +4 -0
- package/dist/providers/claude-provider.js +29 -0
- package/dist/providers/claude.d.ts +15 -0
- package/dist/providers/claude.js +105 -0
- package/dist/providers/codex-models.json +135 -0
- package/dist/providers/codex-provider.d.ts +4 -0
- package/dist/providers/codex-provider.js +27 -0
- package/dist/providers/codex-rules.d.ts +9 -0
- package/dist/providers/codex-rules.js +35 -0
- package/dist/providers/codex.d.ts +14 -0
- package/dist/providers/codex.js +52 -0
- package/dist/providers/detect.d.ts +6 -0
- package/dist/providers/detect.js +30 -0
- package/dist/providers/provider.d.ts +25 -0
- package/dist/providers/provider.js +1 -0
- package/dist/providers/registry.d.ts +28 -0
- package/dist/providers/registry.js +118 -0
- package/dist/record-directory.d.ts +27 -0
- package/dist/record-directory.js +114 -0
- package/dist/run-process.d.ts +13 -0
- package/dist/run-process.js +42 -0
- package/dist/serializer.d.ts +9 -0
- package/dist/serializer.js +34 -0
- package/dist/skills.d.ts +21 -0
- package/dist/skills.js +174 -0
- package/dist/tasks/background-limit.d.ts +16 -0
- package/dist/tasks/background-limit.js +55 -0
- package/dist/tasks/end-children.d.ts +34 -0
- package/dist/tasks/end-children.js +53 -0
- package/dist/tasks/give-task.d.ts +14 -0
- package/dist/tasks/give-task.js +33 -0
- package/dist/tasks/task-coordinator.d.ts +52 -0
- package/dist/tasks/task-coordinator.js +323 -0
- package/dist/tasks/task-store.d.ts +49 -0
- package/dist/tasks/task-store.js +197 -0
- package/dist/tasks/task-work.d.ts +47 -0
- package/dist/tasks/task-work.js +28 -0
- package/dist/tasks/waiting-child.d.ts +51 -0
- package/dist/tasks/waiting-child.js +143 -0
- package/dist/tasks/wake-parent.d.ts +19 -0
- package/dist/tasks/wake-parent.js +109 -0
- package/dist/tasks/wiring.d.ts +51 -0
- package/dist/tasks/wiring.js +151 -0
- package/dist/title-file.d.ts +2 -0
- package/dist/title-file.js +55 -0
- package/dist/usage/accounts.d.ts +15 -0
- package/dist/usage/accounts.js +64 -0
- package/dist/usage/aggregate.d.ts +12 -0
- package/dist/usage/aggregate.js +154 -0
- package/dist/usage/exchange.d.ts +16 -0
- package/dist/usage/exchange.js +84 -0
- package/dist/usage/index-file.d.ts +15 -0
- package/dist/usage/index-file.js +123 -0
- package/dist/usage/limits/monitor.d.ts +50 -0
- package/dist/usage/limits/monitor.js +179 -0
- package/dist/usage/limits/normalize.d.ts +21 -0
- package/dist/usage/limits/normalize.js +160 -0
- package/dist/usage/limits/probe.d.ts +9 -0
- package/dist/usage/limits/probe.js +113 -0
- package/dist/usage/prices-snapshot.json +1071 -0
- package/dist/usage/pricing.d.ts +34 -0
- package/dist/usage/pricing.js +186 -0
- package/dist/usage/projects.d.ts +17 -0
- package/dist/usage/projects.js +49 -0
- package/dist/usage/readers/claude.d.ts +3 -0
- package/dist/usage/readers/claude.js +59 -0
- package/dist/usage/readers/codex.d.ts +23 -0
- package/dist/usage/readers/codex.js +155 -0
- package/dist/usage/record.d.ts +15 -0
- package/dist/usage/record.js +39 -0
- package/dist/usage/roots.d.ts +12 -0
- package/dist/usage/roots.js +29 -0
- package/dist/usage/scanner.d.ts +30 -0
- package/dist/usage/scanner.js +234 -0
- package/dist/usage/usage-service.d.ts +35 -0
- package/dist/usage/usage-service.js +130 -0
- package/dist/watch-seam.d.ts +29 -0
- package/dist/watch-seam.js +78 -0
- package/dist/watch-test-helpers.d.ts +28 -0
- package/dist/watch-test-helpers.js +86 -0
- package/package.json +42 -3
- package/src/async.ts +40 -0
- package/src/chat/attachment-store.ts +108 -0
- package/src/chat/backend.ts +199 -0
- package/src/chat/background-work.ts +42 -0
- package/src/chat/bookmark-store.ts +166 -0
- package/src/chat/chat-core.ts +1228 -0
- package/src/chat/chat-log.ts +187 -0
- package/src/chat/chat-process.ts +237 -0
- package/src/chat/chat-session.ts +1723 -0
- package/src/chat/chat-store.ts +261 -0
- package/src/chat/chat-title.ts +90 -0
- package/src/chat/claude-backend.ts +235 -0
- package/src/chat/claude-protocol.ts +684 -0
- package/src/chat/claude-title.ts +106 -0
- package/src/chat/claude-transcript.ts +233 -0
- package/src/chat/codex-backend.ts +397 -0
- package/src/chat/codex-protocol.ts +872 -0
- package/src/chat/codex-thread.ts +162 -0
- package/src/chat/codex-transport.ts +224 -0
- package/src/chat/composer-preferences.ts +67 -0
- package/src/chat/context-breakdown.ts +80 -0
- package/src/chat/delta-coalescer.ts +62 -0
- package/src/chat/errors.ts +25 -0
- package/src/chat/fake-claude.ts +1006 -0
- package/src/chat/fake-cli.ts +199 -0
- package/src/chat/fake-codex.ts +534 -0
- package/src/chat/fixtures/claude-2.1.285-auto-fallback.json +24 -0
- package/src/chat/fixtures/claude-2.1.285-native-children.json +6600 -0
- package/src/chat/fixtures/claude-2.1.285-resume-direct-compact.json +202 -0
- package/src/chat/fixtures/claude-2.1.285-resume-task-notification.json +57 -0
- package/src/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a4c2e8f10b3d5a7e9.jsonl +10 -0
- package/src/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a4c2e8f10b3d5a7e9.meta.json +1 -0
- package/src/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a9b8c7d6e5f4a3b21.jsonl +2 -0
- package/src/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a9b8c7d6e5f4a3b21.meta.json +1 -0
- package/src/chat/fixtures/codex-0.159.2-native-approval.json +119 -0
- package/src/chat/fixtures/codex-0.159.2-native-file-approval.json +136 -0
- package/src/chat/fixtures/codex-0.159.2-native-interacted.json +220 -0
- package/src/chat/fixtures/codex-0.159.2-usage-windows.json +74 -0
- package/src/chat/input.ts +89 -0
- package/src/chat/limit-resume.ts +74 -0
- package/src/chat/projector.ts +969 -0
- package/src/chat/request-summary.ts +168 -0
- package/src/chat/subagent-projection.ts +45 -0
- package/src/chat/subagent-reader.ts +469 -0
- package/src/chat/subagent-settlement.ts +111 -0
- package/src/chat/thread.ts +167 -0
- package/src/chat/wake-chat.ts +45 -0
- package/src/client-sinks.ts +39 -0
- package/src/coded-error.ts +18 -0
- package/src/context/argv.ts +61 -0
- package/src/context/refusal.ts +50 -0
- package/src/context/verb.ts +392 -0
- package/src/error-text.ts +28 -0
- package/src/events.ts +9 -0
- package/src/fs.ts +118 -0
- package/src/host/agent-host.ts +124 -0
- package/src/host/environment.ts +31 -0
- package/src/host/handlers.ts +142 -0
- package/src/host/memory-port.ts +27 -0
- package/src/host/wiring.ts +164 -0
- package/src/lineage.ts +159 -0
- package/src/messages/deliver-message.ts +61 -0
- package/src/messages/deliver-notice.ts +120 -0
- package/src/messages/notice-notes.ts +34 -0
- package/src/messages/notice-store.ts +142 -0
- package/src/modes.ts +38 -0
- package/src/outbox/manual-clock.ts +31 -0
- package/src/outbox/outbox-worker.ts +214 -0
- package/src/outbox/outbox.ts +106 -0
- package/src/providers/accounts/accounts.ts +192 -0
- package/src/providers/accounts/launch.ts +55 -0
- package/src/providers/accounts/service.ts +632 -0
- package/src/providers/accounts/shadow-home.ts +85 -0
- package/src/providers/accounts/status.ts +106 -0
- package/src/providers/accounts/store.ts +158 -0
- package/src/providers/accounts/test-accounts.ts +48 -0
- package/src/providers/accounts/variables.ts +132 -0
- package/src/providers/catalog.ts +90 -0
- package/src/providers/claude-models.json +114 -0
- package/src/providers/claude-provider.ts +32 -0
- package/src/providers/claude.ts +123 -0
- package/src/providers/codex-models.json +135 -0
- package/src/providers/codex-provider.ts +30 -0
- package/src/providers/codex-rules.ts +54 -0
- package/src/providers/codex.ts +69 -0
- package/src/providers/detect.ts +40 -0
- package/src/providers/provider.ts +46 -0
- package/src/providers/registry.ts +150 -0
- package/src/record-directory.ts +136 -0
- package/src/run-process.ts +61 -0
- package/src/serializer.ts +41 -0
- package/src/skills.ts +199 -0
- package/src/tasks/background-limit.ts +72 -0
- package/src/tasks/end-children.ts +100 -0
- package/src/tasks/give-task.ts +52 -0
- package/src/tasks/task-coordinator.ts +384 -0
- package/src/tasks/task-store.ts +236 -0
- package/src/tasks/task-work.ts +62 -0
- package/src/tasks/waiting-child.ts +203 -0
- package/src/tasks/wake-parent.ts +142 -0
- package/src/tasks/wiring.ts +231 -0
- package/src/title-file.ts +57 -0
- package/src/usage/accounts.ts +86 -0
- package/src/usage/aggregate.ts +220 -0
- package/src/usage/exchange.ts +93 -0
- package/src/usage/index-file.ts +178 -0
- package/src/usage/limits/monitor.ts +239 -0
- package/src/usage/limits/normalize.ts +188 -0
- package/src/usage/limits/probe.ts +120 -0
- package/src/usage/prices-snapshot.json +1071 -0
- package/src/usage/pricing.ts +236 -0
- package/src/usage/projects.ts +65 -0
- package/src/usage/readers/claude.ts +60 -0
- package/src/usage/readers/codex.ts +196 -0
- package/src/usage/record.ts +60 -0
- package/src/usage/roots.ts +39 -0
- package/src/usage/scanner.ts +265 -0
- package/src/usage/usage-service.ts +161 -0
- package/src/watch-seam.ts +111 -0
- package/src/watch-test-helpers.ts +102 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { mkdir, readFile, rm } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { CHAT_BOOKMARK_LIMITS, ChatBookmarksSchema, clipText } from '@adecore/agent-contracts';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { isNotFound, writeAtomic } from '../fs.js';
|
|
6
|
+
import { KeyedSerializer } from '../serializer.js';
|
|
7
|
+
import { ChatError } from './errors.js';
|
|
8
|
+
const SUFFIX = '.bookmarks.json';
|
|
9
|
+
const BookmarkFileSchema = z.object({ version: z.literal(1), bookmarks: ChatBookmarksSchema });
|
|
10
|
+
export function bookmarkFileName(chatId) {
|
|
11
|
+
return `${encodeURIComponent(chatId)}${SUFFIX}`;
|
|
12
|
+
}
|
|
13
|
+
/* Whether a name in the chats folder is a bookmarks file, which the chat records beside it must not count as a chat. */
|
|
14
|
+
export function isBookmarkFileName(name) {
|
|
15
|
+
return name.endsWith(SUFFIX);
|
|
16
|
+
}
|
|
17
|
+
/* A name as it is kept: trimmed, and none at all when nothing is left. */
|
|
18
|
+
function cleanName(name) {
|
|
19
|
+
const trimmed = name === undefined ? undefined : clipText(name.trim(), CHAT_BOOKMARK_LIMITS.name);
|
|
20
|
+
return trimmed === undefined || trimmed === '' ? undefined : trimmed;
|
|
21
|
+
}
|
|
22
|
+
function named(bookmark, name) {
|
|
23
|
+
const { name: _previous, ...rest } = bookmark;
|
|
24
|
+
return name === undefined ? rest : { ...rest, name };
|
|
25
|
+
}
|
|
26
|
+
/*
|
|
27
|
+
* The bookmarks of every chat, one file per chat beside its record under `<home>/chats`, apart
|
|
28
|
+
* from the record, which is rewritten on every turn. One chain per chat puts two clients' clicks
|
|
29
|
+
* after each other, and every change is told to the listeners from inside that chain, so the lists
|
|
30
|
+
* go out in the order they were written.
|
|
31
|
+
*/
|
|
32
|
+
export class BookmarkStore {
|
|
33
|
+
dir;
|
|
34
|
+
writes = new KeyedSerializer();
|
|
35
|
+
listeners = new Set();
|
|
36
|
+
constructor(home) {
|
|
37
|
+
this.dir = join(home, 'chats');
|
|
38
|
+
}
|
|
39
|
+
listen(listener) {
|
|
40
|
+
this.listeners.add(listener);
|
|
41
|
+
return () => {
|
|
42
|
+
this.listeners.delete(listener);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/* The bookmarks of one chat in the order they were made, after any write still on its way. */
|
|
46
|
+
read(chatId) {
|
|
47
|
+
return this.writes.run(chatId, () => this.readFile(chatId));
|
|
48
|
+
}
|
|
49
|
+
/* Marks a message; one that already has a bookmark keeps it, and takes the name when one is given. */
|
|
50
|
+
add(chatId, input, now) {
|
|
51
|
+
return this.change(chatId, (bookmarks) => {
|
|
52
|
+
const name = cleanName(input.name);
|
|
53
|
+
const existing = bookmarks.find((bookmark) => bookmark.itemId === input.itemId);
|
|
54
|
+
if (existing) {
|
|
55
|
+
return name === undefined ? null : bookmarks.map((bookmark) => (bookmark === existing ? named(bookmark, name) : bookmark));
|
|
56
|
+
}
|
|
57
|
+
if (bookmarks.length >= CHAT_BOOKMARK_LIMITS.perChat) {
|
|
58
|
+
throw new ChatError('too-many-bookmarks', `This chat already keeps ${CHAT_BOOKMARK_LIMITS.perChat} bookmarks; remove one first`);
|
|
59
|
+
}
|
|
60
|
+
const excerpt = clipText(input.excerpt, CHAT_BOOKMARK_LIMITS.excerpt);
|
|
61
|
+
return [...bookmarks, named({ itemId: input.itemId, excerpt, createdAt: now }, name)];
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
rename(chatId, itemId, name) {
|
|
65
|
+
return this.change(chatId, (bookmarks) => {
|
|
66
|
+
if (!bookmarks.some((bookmark) => bookmark.itemId === itemId)) {
|
|
67
|
+
throw new ChatError('bookmark-not-found', `This chat has no bookmark on ${itemId}`);
|
|
68
|
+
}
|
|
69
|
+
return bookmarks.map((bookmark) => (bookmark.itemId === itemId ? named(bookmark, cleanName(name)) : bookmark));
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
remove(chatId, itemId) {
|
|
73
|
+
return this.change(chatId, (bookmarks) => bookmarks.some((bookmark) => bookmark.itemId === itemId) ? bookmarks.filter((bookmark) => bookmark.itemId !== itemId) : null);
|
|
74
|
+
}
|
|
75
|
+
/* The bookmarks go with the chat or with a clear of it. A file that no longer parses goes too, since nothing could show it again. */
|
|
76
|
+
removeChat(chatId) {
|
|
77
|
+
return this.writes.run(chatId, async () => {
|
|
78
|
+
const had = await this.readFile(chatId).then((bookmarks) => bookmarks.length > 0, () => true);
|
|
79
|
+
await rm(join(this.dir, bookmarkFileName(chatId)), { force: true });
|
|
80
|
+
if (had) {
|
|
81
|
+
this.tell(chatId, []);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/* A fork keeps the bookmarks on the messages it copied, which are the ones up to where it was cut. */
|
|
86
|
+
async copyChat(fromChatId, toChatId, keep) {
|
|
87
|
+
const kept = (await this.read(fromChatId)).filter((bookmark) => keep(bookmark.itemId));
|
|
88
|
+
if (kept.length === 0) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
await this.writes.run(toChatId, async () => {
|
|
92
|
+
await this.writeFile(toChatId, kept);
|
|
93
|
+
this.tell(toChatId, kept);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/* One read, one decision and one write in the chat's chain; a change that returns null changes nothing and tells nobody. */
|
|
97
|
+
change(chatId, decide) {
|
|
98
|
+
return this.writes.run(chatId, async () => {
|
|
99
|
+
const bookmarks = await this.readFile(chatId);
|
|
100
|
+
const next = decide(bookmarks);
|
|
101
|
+
if (next === null) {
|
|
102
|
+
return bookmarks;
|
|
103
|
+
}
|
|
104
|
+
await this.writeFile(chatId, next);
|
|
105
|
+
this.tell(chatId, next);
|
|
106
|
+
return next;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
tell(chatId, bookmarks) {
|
|
110
|
+
for (const listener of this.listeners) {
|
|
111
|
+
listener(chatId, bookmarks);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async readFile(chatId) {
|
|
115
|
+
let raw;
|
|
116
|
+
try {
|
|
117
|
+
raw = await readFile(join(this.dir, bookmarkFileName(chatId)), 'utf8');
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
if (isNotFound(e)) {
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
throw e;
|
|
124
|
+
}
|
|
125
|
+
// A file that does not parse is refused rather than read as empty, which the next write would make true.
|
|
126
|
+
const parsed = BookmarkFileSchema.safeParse(JSON.parse(raw));
|
|
127
|
+
if (!parsed.success) {
|
|
128
|
+
throw new Error(`The bookmarks file of chat ${chatId} is not valid: ${parsed.error.issues[0]?.message ?? 'unknown problem'}`);
|
|
129
|
+
}
|
|
130
|
+
return parsed.data.bookmarks;
|
|
131
|
+
}
|
|
132
|
+
async writeFile(chatId, bookmarks) {
|
|
133
|
+
const path = join(this.dir, bookmarkFileName(chatId));
|
|
134
|
+
if (bookmarks.length === 0) {
|
|
135
|
+
await rm(path, { force: true });
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
await mkdir(this.dir, { recursive: true, mode: 0o700 });
|
|
139
|
+
await writeAtomic(path, JSON.stringify({ version: 1, bookmarks }));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { type AgentKind, type ChatAttachment, type ChatAttachResult, type ChatAttachmentUpload, type ChatBookmark, type ChatCheckpointDiff, type ChatConfigurePayload, type ChatCreatePayload, type ChatEvent, type ChatHistoryResult, type ChatInfo, type ChatItem, type ChatQueuedMessage, type ChatSkill, type ChatSubagentPayload, type ChatSubagentResult, type ChatTurnItem, type ModelSelection, type RuntimeMode } from '@adecore/agent-contracts';
|
|
2
|
+
import { ClientSinks } from '../client-sinks.ts';
|
|
3
|
+
import type { AgentEvent, AgentSink } from '../events.ts';
|
|
4
|
+
import type { OutboxOutcome } from '../outbox/outbox-worker.ts';
|
|
5
|
+
import { type AccountLaunches } from '../providers/accounts/launch.ts';
|
|
6
|
+
import type { ProviderRegistry } from '../providers/registry.ts';
|
|
7
|
+
import { SkillIndex } from '../skills.ts';
|
|
8
|
+
import type { LimitsUpdate } from '../usage/limits/normalize.ts';
|
|
9
|
+
import type { AttachmentStore } from './attachment-store.ts';
|
|
10
|
+
import type { BookmarkStore } from './bookmark-store.ts';
|
|
11
|
+
import type { SpawnChatProcess } from './chat-process.ts';
|
|
12
|
+
import { ChatSession, type ChatReferences, type ChatSendExtras, type PromptNotes, type ResumeWords, type TurnCheckpoints } from './chat-session.ts';
|
|
13
|
+
import type { ChatRecord, ChatRecordExtras, ChatStore } from './chat-store.ts';
|
|
14
|
+
import type { ChatTitleInput } from './chat-title.ts';
|
|
15
|
+
import type { CodexProcessSpec } from './codex-thread.ts';
|
|
16
|
+
import type { CodexClientInfo } from './codex-transport.ts';
|
|
17
|
+
import { ComposerPreferences } from './composer-preferences.ts';
|
|
18
|
+
import { DeltaCoalescer } from './delta-coalescer.ts';
|
|
19
|
+
import { type BackgroundWork } from './background-work.ts';
|
|
20
|
+
import { SubagentReader, type SubagentReaderOptions } from './subagent-reader.ts';
|
|
21
|
+
export interface InterruptedRun {
|
|
22
|
+
chatId: string;
|
|
23
|
+
turnId: string;
|
|
24
|
+
attempt: number;
|
|
25
|
+
}
|
|
26
|
+
export interface ChatCoreOptions {
|
|
27
|
+
providers: ProviderRegistry;
|
|
28
|
+
store?: ChatStore;
|
|
29
|
+
checkpoints?: TurnCheckpoints;
|
|
30
|
+
env?: Record<string, string | undefined>;
|
|
31
|
+
instructions?: string;
|
|
32
|
+
command?: string[];
|
|
33
|
+
codexCommand?: string[];
|
|
34
|
+
spawn?: SpawnChatProcess;
|
|
35
|
+
codexClient?: CodexClientInfo;
|
|
36
|
+
skills?: SkillIndex;
|
|
37
|
+
attachments: AttachmentStore;
|
|
38
|
+
bookmarks?: BookmarkStore;
|
|
39
|
+
onLimits?: (update: LimitsUpdate) => void;
|
|
40
|
+
claudeTitles?: {
|
|
41
|
+
forSession(agentSessionId: string, projectsDir: string): Promise<string | null>;
|
|
42
|
+
};
|
|
43
|
+
nameChat?: (provider: AgentKind, input: ChatTitleInput) => Promise<string | null>;
|
|
44
|
+
subagents?: Partial<Pick<SubagentReaderOptions, 'claudeProjectsDir' | 'seams' | 'now' | 'listOnce'>>;
|
|
45
|
+
onInterruptedRun?: (run: InterruptedRun) => Promise<boolean>;
|
|
46
|
+
limitResume?: {
|
|
47
|
+
allowed(): boolean;
|
|
48
|
+
now(): number;
|
|
49
|
+
owe(chatId: string, turnId: string, at: number): Promise<void>;
|
|
50
|
+
lapse(chatId: string): Promise<void>;
|
|
51
|
+
owed(chatId: string): boolean;
|
|
52
|
+
};
|
|
53
|
+
accounts?: AccountLaunches;
|
|
54
|
+
}
|
|
55
|
+
export declare class ChatCore {
|
|
56
|
+
protected readonly providers: ProviderRegistry;
|
|
57
|
+
protected readonly store: ChatStore | null;
|
|
58
|
+
protected readonly bookmarks: BookmarkStore | null;
|
|
59
|
+
protected readonly accounts: AccountLaunches | null;
|
|
60
|
+
protected readonly attachments: AttachmentStore;
|
|
61
|
+
protected readonly env: Record<string, string>;
|
|
62
|
+
protected readonly chats: Map<string, ChatSession>;
|
|
63
|
+
protected readonly creating: Map<string, Promise<{
|
|
64
|
+
chatId: string;
|
|
65
|
+
provider: "apple" | "claude" | "codex" | "copilot" | "gemini";
|
|
66
|
+
account?: string | undefined;
|
|
67
|
+
cwd: string;
|
|
68
|
+
agentSessionId: string | null;
|
|
69
|
+
model: string | null;
|
|
70
|
+
selection: {
|
|
71
|
+
model: string;
|
|
72
|
+
options: Record<string, string | boolean>;
|
|
73
|
+
};
|
|
74
|
+
runtimeMode: "auto" | "auto-accept-edits" | "full-access" | "supervised";
|
|
75
|
+
effectiveRuntimeMode?: "auto" | "auto-accept-edits" | "full-access" | "supervised" | undefined;
|
|
76
|
+
permissionMode?: string | undefined;
|
|
77
|
+
status: "error" | "exited" | "idle" | "needs-you" | "running";
|
|
78
|
+
running: boolean;
|
|
79
|
+
activeTurnId: string | null;
|
|
80
|
+
slashCommands: string[];
|
|
81
|
+
skills?: string[] | undefined;
|
|
82
|
+
queue?: {
|
|
83
|
+
id: string;
|
|
84
|
+
turnId?: string | undefined;
|
|
85
|
+
text: string;
|
|
86
|
+
mentions?: string[] | undefined;
|
|
87
|
+
skills?: string[] | undefined;
|
|
88
|
+
chats?: string[] | undefined;
|
|
89
|
+
attachments?: {
|
|
90
|
+
id: string;
|
|
91
|
+
name: string;
|
|
92
|
+
mime: string;
|
|
93
|
+
size: number;
|
|
94
|
+
path: string;
|
|
95
|
+
}[] | undefined;
|
|
96
|
+
createdAt: number;
|
|
97
|
+
}[] | undefined;
|
|
98
|
+
queuePaused?: boolean | undefined;
|
|
99
|
+
background?: {
|
|
100
|
+
id: string;
|
|
101
|
+
kind: "monitor" | "shell";
|
|
102
|
+
description: string;
|
|
103
|
+
command: string | null;
|
|
104
|
+
startedAt: number;
|
|
105
|
+
}[] | undefined;
|
|
106
|
+
delegating?: boolean | undefined;
|
|
107
|
+
usage: {
|
|
108
|
+
contextTokens: number;
|
|
109
|
+
contextWindow: number | null;
|
|
110
|
+
costUsd: number;
|
|
111
|
+
turns: number;
|
|
112
|
+
breakdown?: {
|
|
113
|
+
toolOutput: number;
|
|
114
|
+
filesRead: number;
|
|
115
|
+
conversation: number;
|
|
116
|
+
system: number;
|
|
117
|
+
} | undefined;
|
|
118
|
+
};
|
|
119
|
+
suggestedTitle?: string | undefined;
|
|
120
|
+
hidden?: boolean | undefined;
|
|
121
|
+
forkOf?: {
|
|
122
|
+
chatId: string;
|
|
123
|
+
turnId: string;
|
|
124
|
+
at: number;
|
|
125
|
+
} | undefined;
|
|
126
|
+
resumeAtReset?: boolean | undefined;
|
|
127
|
+
limit?: {
|
|
128
|
+
kind: "overload" | "usage";
|
|
129
|
+
resetsAt?: number | undefined;
|
|
130
|
+
} | undefined;
|
|
131
|
+
resumeAt?: number | undefined;
|
|
132
|
+
requests?: {
|
|
133
|
+
requestId: string;
|
|
134
|
+
itemId: string;
|
|
135
|
+
kind: "approval" | "question";
|
|
136
|
+
createdAt: number;
|
|
137
|
+
approval?: {
|
|
138
|
+
toolName: string;
|
|
139
|
+
subject: string;
|
|
140
|
+
description: string | null;
|
|
141
|
+
path?: string | undefined;
|
|
142
|
+
files?: number | undefined;
|
|
143
|
+
diff?: string | undefined;
|
|
144
|
+
command?: string | undefined;
|
|
145
|
+
truncated?: boolean | undefined;
|
|
146
|
+
canAllowAlways: boolean;
|
|
147
|
+
allowAlways?: {
|
|
148
|
+
label: string;
|
|
149
|
+
description: string;
|
|
150
|
+
} | undefined;
|
|
151
|
+
} | undefined;
|
|
152
|
+
question?: {
|
|
153
|
+
questions: {
|
|
154
|
+
id: string;
|
|
155
|
+
header: string;
|
|
156
|
+
question: string;
|
|
157
|
+
choices: {
|
|
158
|
+
label: string;
|
|
159
|
+
description: string;
|
|
160
|
+
}[];
|
|
161
|
+
multiSelect: boolean;
|
|
162
|
+
}[];
|
|
163
|
+
async?: boolean | undefined;
|
|
164
|
+
} | undefined;
|
|
165
|
+
}[] | undefined;
|
|
166
|
+
createdAt: number;
|
|
167
|
+
}>>;
|
|
168
|
+
protected readonly sinks: ClientSinks<AgentEvent>;
|
|
169
|
+
protected readonly attached: Map<string, Set<string>>;
|
|
170
|
+
protected readonly coalescers: Map<string, DeltaCoalescer>;
|
|
171
|
+
protected readonly subagents: SubagentReader;
|
|
172
|
+
readonly claudeProjectsDir: string;
|
|
173
|
+
readonly composerPreferences: ComposerPreferences;
|
|
174
|
+
private readonly checkpoints;
|
|
175
|
+
private readonly instructions;
|
|
176
|
+
private readonly skillIndex;
|
|
177
|
+
private readonly onLimits;
|
|
178
|
+
private readonly commands;
|
|
179
|
+
private readonly spawn;
|
|
180
|
+
private readonly codexClient;
|
|
181
|
+
private readonly announced;
|
|
182
|
+
private readonly logs;
|
|
183
|
+
private readonly sizes;
|
|
184
|
+
private readonly waiting;
|
|
185
|
+
private readonly unlogged;
|
|
186
|
+
private readonly writes;
|
|
187
|
+
private readonly activity;
|
|
188
|
+
private readonly observers;
|
|
189
|
+
private readonly claudeTitles;
|
|
190
|
+
private readonly nameChat;
|
|
191
|
+
private readonly onInterruptedRun;
|
|
192
|
+
private readonly limitResume;
|
|
193
|
+
constructor(options: ChatCoreOptions);
|
|
194
|
+
codexProcess(info: Pick<ChatInfo, 'cwd' | 'account'>): CodexProcessSpec;
|
|
195
|
+
claudeProjectsDirOf(info: Pick<ChatInfo, 'account'>): string;
|
|
196
|
+
canContinue(kind: AgentKind, from: string | undefined, to: string | undefined): boolean;
|
|
197
|
+
requireAccount(kind: AgentKind, account: string | undefined): void;
|
|
198
|
+
accountLabel(kind: AgentKind, account: string | undefined): string;
|
|
199
|
+
readChat(chatId: string): Promise<{
|
|
200
|
+
info: ChatInfo;
|
|
201
|
+
items: ChatItem[];
|
|
202
|
+
} | null>;
|
|
203
|
+
startingPoint(provider: AgentKind, selection?: ModelSelection): {
|
|
204
|
+
selection: ModelSelection;
|
|
205
|
+
runtimeMode?: RuntimeMode;
|
|
206
|
+
contextWindow: number | null;
|
|
207
|
+
};
|
|
208
|
+
observe(sink: AgentSink): () => void;
|
|
209
|
+
subscribe(clientId: string, sink: AgentSink): () => void;
|
|
210
|
+
create(payload: ChatCreatePayload): Promise<ChatInfo>;
|
|
211
|
+
private createNow;
|
|
212
|
+
storedBackground(chatId: string): Promise<{
|
|
213
|
+
turnId: string | null;
|
|
214
|
+
items: BackgroundWork[];
|
|
215
|
+
commands: string[];
|
|
216
|
+
}>;
|
|
217
|
+
save(chatId: string): Promise<void>;
|
|
218
|
+
isLoading(chatId: string): boolean;
|
|
219
|
+
configure(payload: ChatConfigurePayload): ChatInfo;
|
|
220
|
+
protected switchAccount(session: ChatSession, requested: string): void;
|
|
221
|
+
attach(chatId: string, clientId: string, historyLimit?: number, since?: number): ChatAttachResult;
|
|
222
|
+
attachWithBookmarks(chatId: string, clientId: string, historyLimit?: number, since?: number): Promise<ChatAttachResult>;
|
|
223
|
+
addBookmark(chatId: string, itemId: string, name?: string): Promise<ChatBookmark[]>;
|
|
224
|
+
renameBookmark(chatId: string, itemId: string, name: string): Promise<ChatBookmark[]>;
|
|
225
|
+
removeBookmark(chatId: string, itemId: string): Promise<ChatBookmark[]>;
|
|
226
|
+
private requireBookmarks;
|
|
227
|
+
history(chatId: string, cursor: string, limit?: number): ChatHistoryResult;
|
|
228
|
+
detach(chatId: string, clientId: string): void;
|
|
229
|
+
detachAll(clientId: string): void;
|
|
230
|
+
subagent(clientId: string, payload: ChatSubagentPayload): Promise<ChatSubagentResult>;
|
|
231
|
+
stopSubagent(chatId: string, toolUseId: string): Promise<void>;
|
|
232
|
+
stopTask(chatId: string, taskId: string): Promise<void>;
|
|
233
|
+
subagentItems(chatId: string, toolUseId: string): Promise<ChatItem[]>;
|
|
234
|
+
hasStored(chatId: string): Promise<boolean>;
|
|
235
|
+
lastTurn(chatId: string): Promise<ChatTurnItem | null>;
|
|
236
|
+
addNote(chatId: string, level: 'info' | 'warning' | 'error', text: string): Promise<void>;
|
|
237
|
+
deliverNote(chatId: string, delivery: {
|
|
238
|
+
noteId: string;
|
|
239
|
+
note: string;
|
|
240
|
+
from?: string;
|
|
241
|
+
preamble: string;
|
|
242
|
+
}): Promise<boolean>;
|
|
243
|
+
send(chatId: string, text: string, extras?: ChatSendExtras, uploads?: ChatAttachmentUpload[]): Promise<{
|
|
244
|
+
queued: boolean;
|
|
245
|
+
turnId: string;
|
|
246
|
+
}>;
|
|
247
|
+
attachment(chatId: string, id: string): ChatAttachment | null;
|
|
248
|
+
unqueue(chatId: string, messageId: string): ChatQueuedMessage;
|
|
249
|
+
sendNow(chatId: string, messageId: string): void;
|
|
250
|
+
skills(chatId: string): Promise<ChatSkill[]>;
|
|
251
|
+
compact(chatId: string): void;
|
|
252
|
+
clear(chatId: string, force?: boolean): Promise<void>;
|
|
253
|
+
cancel(chatId: string, subagents?: boolean): void;
|
|
254
|
+
turnDiff(chatId: string, turnId: string): Promise<ChatCheckpointDiff | null>;
|
|
255
|
+
approve(chatId: string, requestId: string, decision: 'allow' | 'allow-always' | 'deny', message?: string): void;
|
|
256
|
+
answer(chatId: string, requestId: string, answers: Record<string, string>): void;
|
|
257
|
+
dismiss(chatId: string, itemId: string): void;
|
|
258
|
+
kill(chatId: string): Promise<void>;
|
|
259
|
+
stop(chatId: string, reason: string): Promise<void>;
|
|
260
|
+
processTargets(): {
|
|
261
|
+
id: string;
|
|
262
|
+
pid: number;
|
|
263
|
+
provider: AgentKind;
|
|
264
|
+
status: ChatInfo['status'];
|
|
265
|
+
updatedAt: number;
|
|
266
|
+
}[];
|
|
267
|
+
list(): ChatInfo[];
|
|
268
|
+
get(chatId: string): ChatSession | undefined;
|
|
269
|
+
resumeRun(chatId: string, turnId: string, attempt: number): Promise<void>;
|
|
270
|
+
takeUpAfterLimit(chatId: string, turnId: string): Promise<OutboxOutcome>;
|
|
271
|
+
resumeSettingChanged(): void;
|
|
272
|
+
abandonRun(chatId: string, turnId: string, reason: string): void;
|
|
273
|
+
recoverInterrupted(): Promise<void>;
|
|
274
|
+
shutdown(): Promise<void>;
|
|
275
|
+
persistAllSync(): void;
|
|
276
|
+
persisted(chatId: string): Promise<void>;
|
|
277
|
+
protected loaded(chatId: string): Promise<void>;
|
|
278
|
+
protected persist(chatId: string): void;
|
|
279
|
+
protected require(chatId: string): ChatSession;
|
|
280
|
+
protected instructionsFor(_chatId: string): string | null;
|
|
281
|
+
protected resumeNoteFor(_chatId: string): string | null;
|
|
282
|
+
protected foldersFor(_chatId: string): readonly string[];
|
|
283
|
+
protected hiddenFor(_chatId: string): boolean;
|
|
284
|
+
protected promptNotesFor(_chatId: string): PromptNotes | undefined;
|
|
285
|
+
protected referencesFor(_chatId: string): ChatReferences | undefined;
|
|
286
|
+
protected envFor(_chatId: string, base: Record<string, string>): Record<string, string | undefined>;
|
|
287
|
+
protected admit(_chatId: string, _cwd: string): Promise<void>;
|
|
288
|
+
protected openingSelection(_chatId: string, _kind: AgentKind): ModelSelection | undefined;
|
|
289
|
+
protected runtimeModeFor(_chatId: string, mode: RuntimeMode): RuntimeMode;
|
|
290
|
+
protected opened(_session: ChatSession, _stored: ChatRecord | null): Promise<void>;
|
|
291
|
+
protected recordExtras(_chatId: string): ChatRecordExtras;
|
|
292
|
+
protected cleared(_chatId: string): Promise<void>;
|
|
293
|
+
protected clearing(_chatId: string): Promise<void>;
|
|
294
|
+
protected forgotten(_chatId: string): void;
|
|
295
|
+
protected removed(_chatId: string, _chat: {
|
|
296
|
+
info: ChatInfo;
|
|
297
|
+
items: ChatItem[];
|
|
298
|
+
}): Promise<void>;
|
|
299
|
+
protected broadcasted(_chatId: string, _event: ChatEvent): void;
|
|
300
|
+
protected endedAt(_chatId: string): number | null;
|
|
301
|
+
protected unownedReason(_chatId: string): string;
|
|
302
|
+
protected resumeWords(_chatId: string): Promise<ResumeWords>;
|
|
303
|
+
private persistSoon;
|
|
304
|
+
private cancelWaiting;
|
|
305
|
+
private persistNow;
|
|
306
|
+
private emit;
|
|
307
|
+
private broadcast;
|
|
308
|
+
private announceStatus;
|
|
309
|
+
private openLog;
|
|
310
|
+
private owedResume;
|
|
311
|
+
}
|