kimaki 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-model.e2e.test.js +250 -164
- package/dist/anthropic-account-identity.js +9 -1
- package/dist/anthropic-auth-plugin.js +10 -13
- package/dist/anthropic-auth-plugin.test.js +17 -0
- package/dist/anthropic-auth-state.js +1 -0
- package/dist/bash-tool-schema-plugin.js +32 -0
- package/dist/bash-tool-schema-plugin.test.js +49 -0
- package/dist/bin.js +73 -19
- package/dist/cli-commands/maintenance.js +46 -7
- package/dist/cli-commands/project.js +11 -27
- package/dist/cli-commands/send.js +30 -1
- package/dist/cli-commands/session.js +322 -90
- package/dist/cli-commands/task.js +34 -15
- package/dist/cli-parsing.test.js +83 -4
- package/dist/cli-runner.js +44 -8
- package/dist/cli-runner.test.js +27 -0
- package/dist/cli-send-thread.e2e.test.js +9 -9
- package/dist/cli.js +32 -0
- package/dist/commands/abort.js +5 -1
- package/dist/commands/action-buttons.js +2 -1
- package/dist/commands/add-project.js +4 -7
- package/dist/commands/agent.js +164 -32
- package/dist/commands/ask-question.js +23 -33
- package/dist/commands/ask-question.test.js +43 -1
- package/dist/commands/btw.js +28 -6
- package/dist/commands/file-upload.js +2 -1
- package/dist/commands/fork-subagent.js +2 -4
- package/dist/commands/fork.js +4 -4
- package/dist/commands/last-sessions.js +17 -10
- package/dist/commands/login.js +6 -0
- package/dist/commands/merge-worktree.js +47 -14
- package/dist/commands/model-variant.js +8 -1
- package/dist/commands/model.js +16 -9
- package/dist/commands/multioauth.js +1 -0
- package/dist/commands/new-worktree.js +170 -102
- package/dist/commands/queue.js +3 -2
- package/dist/commands/resume.js +4 -4
- package/dist/commands/session.js +78 -63
- package/dist/commands/user-command.js +6 -8
- package/dist/commands/worktrees.js +5 -13
- package/dist/config.js +16 -1
- package/dist/cpu-profiler.js +211 -0
- package/dist/cpu-profiler.test.js +160 -0
- package/dist/database.js +152 -3
- package/dist/db.js +33 -0
- package/dist/db.test.js +267 -1
- package/dist/default-channel-provisioning.test.js +148 -0
- package/dist/discord-bot.js +517 -488
- package/dist/discord-command-registration.js +25 -10
- package/dist/discord-command-registration.test.js +17 -0
- package/dist/discord-utils.js +97 -5
- package/dist/discord-utils.test.js +151 -1
- package/dist/errors.js +10 -0
- package/dist/exec-async.js +17 -5
- package/dist/external-directory-permissions.e2e.test.js +11 -7
- package/dist/external-directory-project-deny.e2e.test.js +5 -3
- package/dist/external-opencode-sync.js +94 -17
- package/dist/external-opencode-sync.test.js +206 -0
- package/dist/extract-sdk-error-message.test.js +13 -0
- package/dist/file-edit-log.js +197 -0
- package/dist/file-edit-log.test.js +258 -0
- package/dist/format-tables.js +52 -0
- package/dist/format-tables.test.js +93 -0
- package/dist/gateway-proxy-reconnect.e2e.test.js +28 -8
- package/dist/gateway-proxy.e2e.test.js +18 -18
- package/dist/git-worktree-core.js +182 -17
- package/dist/interaction-handler.js +416 -398
- package/dist/ipc-tools-plugin.js +68 -3
- package/dist/kimaki-opencode-plugin-loading.e2e.test.js +122 -58
- package/dist/kimaki-opencode-plugin.js +9 -3
- package/dist/kimaki-workspace-adaptor.js +33 -10
- package/dist/logger.js +11 -1
- package/dist/markdown.js +3 -1
- package/dist/markdown.test.js +11 -3
- package/dist/message-formatting.js +181 -51
- package/dist/message-formatting.test.js +529 -22
- package/dist/message-preprocessing.js +105 -1
- package/dist/oauth-rotation-shared.js +10 -0
- package/dist/openai-auth-plugin.js +1 -0
- package/dist/openai-auth-state.js +1 -0
- package/dist/opencode-command.js +28 -0
- package/dist/opencode-command.test.js +109 -1
- package/dist/opencode-interrupt-plugin.js +4 -0
- package/dist/opencode-interrupt-plugin.test.js +24 -0
- package/dist/opencode.js +82 -15
- package/dist/project-add.test.js +62 -0
- package/dist/question-abort-clears-dropdown.e2e.test.js +89 -0
- package/dist/question-abort-retry-text-before-dropdown.e2e.test.js +150 -0
- package/dist/question-text-before-dropdown.e2e.test.js +52 -0
- package/dist/queue-advanced-abort.e2e.test.js +8 -10
- package/dist/queue-advanced-action-buttons.e2e.test.js +8 -8
- package/dist/queue-advanced-e2e-setup.js +78 -5
- package/dist/queue-advanced-footer.e2e.test.js +60 -269
- package/dist/queue-advanced-model-switch.e2e.test.js +9 -11
- package/dist/queue-advanced-permissions-typing.e2e.test.js +15 -15
- package/dist/queue-advanced-question.e2e.test.js +32 -27
- package/dist/queue-advanced-typing-interrupt.e2e.test.js +10 -12
- package/dist/queue-advanced-typing.e2e.test.js +7 -9
- package/dist/queue-delete-message.e2e.test.js +3 -3
- package/dist/queue-drain-after-interactive-ui.e2e.test.js +5 -5
- package/dist/queue-interrupt-drain.e2e.test.js +122 -12
- package/dist/queue-question-select-drain.e2e.test.js +34 -132
- package/dist/runtime-lifecycle.e2e.test.js +21 -51
- package/dist/schema.js +35 -1
- package/dist/session-handler/event-stream-state.js +391 -50
- package/dist/session-handler/event-stream-state.test.js +736 -8
- package/dist/session-handler/model-utils.js +172 -5
- package/dist/session-handler/model-utils.test.js +445 -0
- package/dist/session-handler/opencode-session-event-log.js +30 -1
- package/dist/session-handler/thread-ingress.test.js +41 -0
- package/dist/session-handler/thread-runtime-state.js +2 -0
- package/dist/session-handler/thread-session-runtime-summary.test.js +121 -0
- package/dist/session-handler/thread-session-runtime.js +574 -299
- package/dist/session-search.js +123 -4
- package/dist/session-search.test.js +248 -1
- package/dist/session-sleep.test.js +224 -0
- package/dist/session-title-rename.test.js +37 -39
- package/dist/sleep.e2e.test.js +494 -0
- package/dist/startup-time.e2e.test.js +2 -1
- package/dist/store.js +3 -0
- package/dist/system-message.js +102 -16
- package/dist/system-message.test.js +192 -15
- package/dist/task-runner.js +96 -5
- package/dist/task-schedule.js +87 -1
- package/dist/task-schedule.test.js +149 -1
- package/dist/test-utils.js +17 -9
- package/dist/thinking-utils.js +10 -0
- package/dist/thinking-utils.test.js +35 -0
- package/dist/thread-message-queue.e2e.test.js +65 -213
- package/dist/undo-redo.e2e.test.js +17 -9
- package/dist/voice-attachment.js +23 -1
- package/dist/voice-handler.js +21 -4
- package/dist/voice-message.e2e.test.js +144 -30
- package/dist/voice-routing-input.e2e.test.js +195 -0
- package/dist/voice-routing-question.e2e.test.js +125 -0
- package/dist/voice.js +28 -8
- package/dist/voice.test.js +96 -30
- package/dist/worktree-clone-isolation.e2e.test.js +188 -0
- package/dist/worktree-lifecycle.e2e.test.js +55 -36
- package/dist/worktrees.js +226 -443
- package/dist/worktrees.test.js +435 -58
- package/dist/xai-auth-plugin.js +1 -0
- package/dist/xai-auth-state.js +1 -0
- package/package.json +8 -6
- package/skills/bump-holocron-consumers/SKILL.md +137 -0
- package/skills/critique/SKILL.md +4 -4
- package/skills/errore/SKILL.md +60 -218
- package/skills/goke/SKILL.md +150 -10
- package/skills/holocron/SKILL.md +154 -17
- package/skills/npm-package/SKILL.md +55 -35
- package/skills/profano/SKILL.md +17 -2
- package/skills/spiceflow/SKILL.md +39 -3
- package/skills/strada/SKILL.md +39 -0
- package/skills/zele/SKILL.md +19 -0
- package/src/agent-model.e2e.test.ts +287 -186
- package/src/anthropic-account-identity.ts +20 -1
- package/src/anthropic-auth-plugin.test.ts +19 -0
- package/src/anthropic-auth-plugin.ts +12 -16
- package/src/anthropic-auth-state.ts +1 -0
- package/src/bash-tool-schema-plugin.test.ts +55 -0
- package/src/bash-tool-schema-plugin.ts +46 -0
- package/src/bin.ts +78 -26
- package/src/cli-commands/maintenance.ts +59 -13
- package/src/cli-commands/project.ts +14 -35
- package/src/cli-commands/send.ts +31 -1
- package/src/cli-commands/session.ts +374 -114
- package/src/cli-commands/task.ts +34 -15
- package/src/cli-parsing.test.ts +103 -4
- package/src/cli-runner.test.ts +49 -0
- package/src/cli-runner.ts +44 -7
- package/src/cli-send-thread.e2e.test.ts +9 -11
- package/src/cli.ts +53 -0
- package/src/commands/abort.ts +6 -1
- package/src/commands/action-buttons.ts +2 -1
- package/src/commands/add-project.ts +4 -8
- package/src/commands/agent.ts +205 -29
- package/src/commands/ask-question.test.ts +48 -1
- package/src/commands/ask-question.ts +23 -33
- package/src/commands/btw.ts +40 -5
- package/src/commands/file-upload.ts +2 -1
- package/src/commands/fork-subagent.ts +2 -3
- package/src/commands/fork.ts +4 -3
- package/src/commands/last-sessions.ts +10 -4
- package/src/commands/login.ts +6 -0
- package/src/commands/merge-worktree.ts +54 -16
- package/src/commands/model-variant.ts +9 -1
- package/src/commands/model.ts +20 -9
- package/src/commands/multioauth.ts +1 -0
- package/src/commands/new-worktree.ts +138 -55
- package/src/commands/queue.ts +3 -2
- package/src/commands/resume.ts +4 -3
- package/src/commands/session.ts +94 -70
- package/src/commands/user-command.ts +6 -6
- package/src/commands/worktrees.ts +5 -12
- package/src/config.ts +18 -1
- package/src/cpu-profiler.test.ts +183 -0
- package/src/cpu-profiler.ts +293 -0
- package/src/database.ts +235 -3
- package/src/db.test.ts +293 -0
- package/src/db.ts +38 -0
- package/src/default-channel-provisioning.test.ts +155 -0
- package/src/discord-bot.ts +78 -36
- package/src/discord-command-registration.test.ts +20 -0
- package/src/discord-command-registration.ts +42 -12
- package/src/discord-utils.test.ts +176 -0
- package/src/discord-utils.ts +152 -7
- package/src/errors.ts +12 -0
- package/src/exec-async.ts +20 -11
- package/src/external-directory-permissions.e2e.test.ts +11 -7
- package/src/external-directory-project-deny.e2e.test.ts +5 -3
- package/src/external-opencode-sync.test.ts +248 -0
- package/src/external-opencode-sync.ts +122 -19
- package/src/extract-sdk-error-message.test.ts +18 -0
- package/src/file-edit-log.test.ts +287 -0
- package/src/file-edit-log.ts +283 -0
- package/src/format-tables.test.ts +101 -0
- package/src/format-tables.ts +75 -0
- package/src/gateway-proxy-reconnect.e2e.test.ts +38 -8
- package/src/gateway-proxy.e2e.test.ts +18 -17
- package/src/git-worktree-core.ts +247 -20
- package/src/interaction-handler.ts +36 -13
- package/src/ipc-tools-plugin.ts +82 -5
- package/src/kimaki-opencode-plugin-loading.e2e.test.ts +188 -97
- package/src/kimaki-opencode-plugin.ts +9 -3
- package/src/kimaki-workspace-adaptor.ts +40 -11
- package/src/logger.ts +14 -4
- package/src/markdown.test.ts +13 -3
- package/src/markdown.ts +4 -1
- package/src/message-formatting.test.ts +672 -25
- package/src/message-formatting.ts +242 -53
- package/src/message-preprocessing.ts +116 -1
- package/src/oauth-rotation-shared.ts +10 -0
- package/src/openai-auth-plugin.ts +1 -0
- package/src/openai-auth-state.ts +1 -0
- package/src/opencode-command.test.ts +140 -0
- package/src/opencode-command.ts +38 -0
- package/src/opencode-interrupt-plugin.test.ts +32 -0
- package/src/opencode-interrupt-plugin.ts +3 -0
- package/src/opencode.ts +115 -15
- package/src/project-add.test.ts +80 -0
- package/src/question-abort-clears-dropdown.e2e.test.ts +109 -0
- package/src/question-abort-retry-text-before-dropdown.e2e.test.ts +172 -0
- package/src/question-text-before-dropdown.e2e.test.ts +67 -0
- package/src/queue-advanced-abort.e2e.test.ts +8 -9
- package/src/queue-advanced-action-buttons.e2e.test.ts +8 -8
- package/src/queue-advanced-e2e-setup.ts +83 -4
- package/src/queue-advanced-footer.e2e.test.ts +67 -315
- package/src/queue-advanced-model-switch.e2e.test.ts +9 -10
- package/src/queue-advanced-permissions-typing.e2e.test.ts +15 -15
- package/src/queue-advanced-question.e2e.test.ts +36 -30
- package/src/queue-advanced-typing-interrupt.e2e.test.ts +11 -11
- package/src/queue-advanced-typing.e2e.test.ts +8 -8
- package/src/queue-delete-message.e2e.test.ts +3 -3
- package/src/queue-drain-after-interactive-ui.e2e.test.ts +5 -5
- package/src/queue-interrupt-drain.e2e.test.ts +133 -12
- package/src/queue-question-select-drain.e2e.test.ts +36 -161
- package/src/runtime-lifecycle.e2e.test.ts +21 -54
- package/src/schema.sql +15 -2
- package/src/schema.ts +37 -1
- package/src/session-handler/event-stream-state.test.ts +790 -7
- package/src/session-handler/event-stream-state.ts +568 -53
- package/src/session-handler/model-utils.test.ts +537 -0
- package/src/session-handler/model-utils.ts +281 -5
- package/src/session-handler/opencode-session-event-log.ts +31 -1
- package/src/session-handler/thread-ingress.test.ts +54 -0
- package/src/session-handler/thread-runtime-state.ts +3 -0
- package/src/session-handler/thread-session-runtime-summary.test.ts +169 -0
- package/src/session-handler/thread-session-runtime.ts +712 -358
- package/src/session-search.test.ts +281 -0
- package/src/session-search.ts +241 -7
- package/src/session-sleep.test.ts +294 -0
- package/src/session-title-rename.test.ts +54 -48
- package/src/sleep.e2e.test.ts +565 -0
- package/src/startup-time.e2e.test.ts +5 -1
- package/src/store.ts +22 -0
- package/src/system-message.test.ts +226 -15
- package/src/system-message.ts +130 -16
- package/src/task-runner.ts +138 -3
- package/src/task-schedule.test.ts +170 -0
- package/src/task-schedule.ts +141 -1
- package/src/test-utils.ts +21 -10
- package/src/thinking-utils.test.ts +46 -0
- package/src/thinking-utils.ts +21 -0
- package/src/thread-message-queue.e2e.test.ts +65 -245
- package/src/undo-redo.e2e.test.ts +17 -9
- package/src/voice-attachment.ts +29 -1
- package/src/voice-handler.ts +23 -4
- package/src/voice-message.e2e.test.ts +149 -29
- package/src/voice-routing-input.e2e.test.ts +203 -0
- package/src/voice-routing-question.e2e.test.ts +131 -0
- package/src/voice.test.ts +107 -29
- package/src/voice.ts +34 -6
- package/src/worktree-clone-isolation.e2e.test.ts +213 -0
- package/src/worktree-lifecycle.e2e.test.ts +55 -35
- package/src/worktrees.test.ts +505 -64
- package/src/worktrees.ts +257 -603
- package/src/xai-auth-plugin.ts +1 -0
- package/src/xai-auth-state.ts +1 -0
- package/dist/message-finish-field.e2e.test.js +0 -169
- package/dist/subagent-rate-limit-plugin.js +0 -184
- package/src/message-finish-field.e2e.test.ts +0 -196
- package/src/subagent-rate-limit-plugin.ts +0 -228
|
@@ -10,6 +10,34 @@ let eventLogWriteDisabled = false;
|
|
|
10
10
|
export function isOpencodeSessionEventLogEnabled() {
|
|
11
11
|
return process.env['KIMAKI_LOG_OPENCODE_SESSION_EVENTS'] === '1';
|
|
12
12
|
}
|
|
13
|
+
function sessionIdFromEventProperties(properties) {
|
|
14
|
+
if (!properties || typeof properties !== 'object') {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const sessionID = Reflect.get(properties, 'sessionID');
|
|
18
|
+
if (typeof sessionID === 'string') {
|
|
19
|
+
return sessionID;
|
|
20
|
+
}
|
|
21
|
+
const info = Reflect.get(properties, 'info');
|
|
22
|
+
if (info && typeof info === 'object') {
|
|
23
|
+
const id = Reflect.get(info, 'id');
|
|
24
|
+
if (typeof id === 'string') {
|
|
25
|
+
return id;
|
|
26
|
+
}
|
|
27
|
+
const infoSessionId = Reflect.get(info, 'sessionID');
|
|
28
|
+
if (typeof infoSessionId === 'string') {
|
|
29
|
+
return infoSessionId;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const part = Reflect.get(properties, 'part');
|
|
33
|
+
if (part && typeof part === 'object') {
|
|
34
|
+
const partSessionId = Reflect.get(part, 'sessionID');
|
|
35
|
+
if (typeof partSessionId === 'string') {
|
|
36
|
+
return partSessionId;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
13
41
|
export function getOpencodeEventSessionId(event) {
|
|
14
42
|
switch (event.type) {
|
|
15
43
|
case 'message.updated':
|
|
@@ -34,7 +62,8 @@ export function getOpencodeEventSessionId(event) {
|
|
|
34
62
|
case 'session.deleted':
|
|
35
63
|
return event.properties.info.id;
|
|
36
64
|
default:
|
|
37
|
-
|
|
65
|
+
// session.next.* and later SDK events put sessionID on properties.
|
|
66
|
+
return sessionIdFromEventProperties(event.properties);
|
|
38
67
|
}
|
|
39
68
|
}
|
|
40
69
|
function sanitizeSessionIdForFilename(sessionId) {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Unit tests for the per-thread Discord arrival FIFO.
|
|
2
|
+
// /plan-agent and a follow-up message must keep Discord order.
|
|
3
|
+
import { describe, expect, test } from 'vitest';
|
|
4
|
+
import { reserveThreadIngress, runInThreadIngressSlot, waitForCurrentThreadIngress, } from './thread-session-runtime.js';
|
|
5
|
+
describe('thread ingress FIFO', () => {
|
|
6
|
+
test('later waiters stay behind an unreleased earlier slot', async () => {
|
|
7
|
+
const first = reserveThreadIngress('thread-fifo');
|
|
8
|
+
const second = reserveThreadIngress('thread-fifo');
|
|
9
|
+
const order = [];
|
|
10
|
+
const firstWork = runInThreadIngressSlot(first, async () => {
|
|
11
|
+
await waitForCurrentThreadIngress();
|
|
12
|
+
order.push('first-write');
|
|
13
|
+
first.release();
|
|
14
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
15
|
+
order.push('first-work');
|
|
16
|
+
});
|
|
17
|
+
const secondWork = runInThreadIngressSlot(second, async () => {
|
|
18
|
+
await waitForCurrentThreadIngress();
|
|
19
|
+
order.push('second');
|
|
20
|
+
second.release();
|
|
21
|
+
});
|
|
22
|
+
await Promise.all([firstWork, secondWork]);
|
|
23
|
+
expect(order).toEqual(['first-write', 'second', 'first-work']);
|
|
24
|
+
});
|
|
25
|
+
test('runInThreadIngressSlot releases after a thrown callback', async () => {
|
|
26
|
+
const first = reserveThreadIngress('thread-fifo-throw');
|
|
27
|
+
const second = reserveThreadIngress('thread-fifo-throw');
|
|
28
|
+
const order = [];
|
|
29
|
+
const firstWork = runInThreadIngressSlot(first, async () => {
|
|
30
|
+
await waitForCurrentThreadIngress();
|
|
31
|
+
order.push('first');
|
|
32
|
+
throw new Error('boom');
|
|
33
|
+
}).catch(() => { });
|
|
34
|
+
const secondWork = runInThreadIngressSlot(second, async () => {
|
|
35
|
+
await waitForCurrentThreadIngress();
|
|
36
|
+
order.push('second');
|
|
37
|
+
});
|
|
38
|
+
await Promise.all([firstWork, secondWork]);
|
|
39
|
+
expect(order).toEqual(['first', 'second']);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
import { ThreadSessionRuntime } from './thread-session-runtime.js';
|
|
3
|
+
function summaryMessageEvent({ sessionId, messageId, }) {
|
|
4
|
+
return {
|
|
5
|
+
id: `evt_${messageId}`,
|
|
6
|
+
type: 'message.updated',
|
|
7
|
+
properties: {
|
|
8
|
+
sessionID: sessionId,
|
|
9
|
+
info: {
|
|
10
|
+
id: messageId,
|
|
11
|
+
sessionID: sessionId,
|
|
12
|
+
role: 'assistant',
|
|
13
|
+
parentID: 'msg_user',
|
|
14
|
+
time: { created: 2, completed: 3 },
|
|
15
|
+
modelID: 'compaction-model',
|
|
16
|
+
providerID: 'test-provider',
|
|
17
|
+
mode: 'compaction',
|
|
18
|
+
agent: 'compaction',
|
|
19
|
+
path: { cwd: '/test', root: '/test' },
|
|
20
|
+
cost: 1,
|
|
21
|
+
tokens: {
|
|
22
|
+
input: 10,
|
|
23
|
+
output: 1,
|
|
24
|
+
reasoning: 0,
|
|
25
|
+
cache: { read: 0, write: 0 },
|
|
26
|
+
},
|
|
27
|
+
finish: 'stop',
|
|
28
|
+
summary: true,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function summaryTextPart({ sessionId, messageId, }) {
|
|
34
|
+
return {
|
|
35
|
+
id: `prt_${messageId}`,
|
|
36
|
+
sessionID: sessionId,
|
|
37
|
+
messageID: messageId,
|
|
38
|
+
type: 'text',
|
|
39
|
+
text: 'internal compaction summary must not reach Discord',
|
|
40
|
+
time: { start: 2, end: 3 },
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
describe('ThreadSessionRuntime compaction summary routing', () => {
|
|
44
|
+
test('drops summary message parts before fallback buffering or completion', async () => {
|
|
45
|
+
const sessionId = 'ses_main';
|
|
46
|
+
const messageId = 'msg_summary_embedded_parts';
|
|
47
|
+
const event = summaryMessageEvent({ sessionId, messageId });
|
|
48
|
+
if (event.type !== 'message.updated') {
|
|
49
|
+
throw new Error('Expected summary message event');
|
|
50
|
+
}
|
|
51
|
+
const message = {
|
|
52
|
+
...event.properties.info,
|
|
53
|
+
parts: [summaryTextPart({ sessionId, messageId })],
|
|
54
|
+
};
|
|
55
|
+
const runtime = Object.create(ThreadSessionRuntime.prototype);
|
|
56
|
+
Object.defineProperty(runtime, 'state', {
|
|
57
|
+
value: { sessionId },
|
|
58
|
+
configurable: true,
|
|
59
|
+
});
|
|
60
|
+
runtime.eventBuffer = [{ event, timestamp: 1 }];
|
|
61
|
+
runtime.partBuffer = new Map();
|
|
62
|
+
runtime.flushBufferedParts = async () => {
|
|
63
|
+
throw new Error('Summary message must not flush parts');
|
|
64
|
+
};
|
|
65
|
+
runtime.handleNaturalAssistantCompletion = async () => {
|
|
66
|
+
throw new Error('Summary message must not complete the Discord turn');
|
|
67
|
+
};
|
|
68
|
+
await runtime.handleMessageUpdated(message);
|
|
69
|
+
expect(runtime.partBuffer.size).toBe(0);
|
|
70
|
+
});
|
|
71
|
+
test.each([
|
|
72
|
+
['main session', 'ses_main'],
|
|
73
|
+
['subagent session', 'ses_child'],
|
|
74
|
+
])('preserves summary identity and drops %s parts before buffering', async (_, sessionId) => {
|
|
75
|
+
const messageId = `msg_summary_${sessionId}`;
|
|
76
|
+
const runtime = Object.create(ThreadSessionRuntime.prototype);
|
|
77
|
+
const compacted = runtime.compactEventForEventBuffer(summaryMessageEvent({ sessionId, messageId }));
|
|
78
|
+
expect(compacted?.type).toBe('message.updated');
|
|
79
|
+
if (!compacted || compacted.type !== 'message.updated') {
|
|
80
|
+
throw new Error('Expected compacted summary message event');
|
|
81
|
+
}
|
|
82
|
+
expect(compacted.properties.info.summary).toBe(true);
|
|
83
|
+
runtime.eventBuffer = [{ event: compacted, timestamp: 1 }];
|
|
84
|
+
runtime.partBuffer = new Map();
|
|
85
|
+
await runtime.handlePartUpdated(summaryTextPart({ sessionId, messageId }));
|
|
86
|
+
expect(runtime.partBuffer.size).toBe(0);
|
|
87
|
+
});
|
|
88
|
+
test.each([
|
|
89
|
+
['main session', 'ses_main'],
|
|
90
|
+
['subagent session', 'ses_child'],
|
|
91
|
+
])('holds %s parts until summary identity arrives, then drops them', async (_, sessionId) => {
|
|
92
|
+
const messageId = `msg_summary_unknown_${sessionId}`;
|
|
93
|
+
const runtime = Object.create(ThreadSessionRuntime.prototype);
|
|
94
|
+
Object.defineProperty(runtime, 'state', {
|
|
95
|
+
value: { sessionId: 'ses_main' },
|
|
96
|
+
configurable: true,
|
|
97
|
+
});
|
|
98
|
+
runtime.eventBuffer = [];
|
|
99
|
+
runtime.partBuffer = new Map();
|
|
100
|
+
runtime.handleMainPart = async () => {
|
|
101
|
+
throw new Error('Unknown summary parts must not render');
|
|
102
|
+
};
|
|
103
|
+
runtime.handleSubtaskPart = async () => {
|
|
104
|
+
throw new Error('Unknown summary parts must not render');
|
|
105
|
+
};
|
|
106
|
+
runtime.flushBufferedParts = async () => {
|
|
107
|
+
throw new Error('Summary message must not flush parts');
|
|
108
|
+
};
|
|
109
|
+
runtime.handleNaturalAssistantCompletion = async () => {
|
|
110
|
+
throw new Error('Summary message must not complete the Discord turn');
|
|
111
|
+
};
|
|
112
|
+
await runtime.handlePartUpdated(summaryTextPart({ sessionId, messageId }));
|
|
113
|
+
expect(runtime.partBuffer.get(messageId)?.size).toBe(1);
|
|
114
|
+
const event = summaryMessageEvent({ sessionId, messageId });
|
|
115
|
+
if (event.type !== 'message.updated') {
|
|
116
|
+
throw new Error('Expected summary message event');
|
|
117
|
+
}
|
|
118
|
+
await runtime.handleMessageUpdated(event.properties.info);
|
|
119
|
+
expect(runtime.partBuffer.size).toBe(0);
|
|
120
|
+
});
|
|
121
|
+
});
|