@openadapter/koda 1.0.0-beta.3
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/CHANGELOG.md +4448 -0
- package/README.md +665 -0
- package/dist/bun/cli.d.ts +2 -0
- package/dist/bun/cli.js +2 -0
- package/dist/bun/register-bedrock.d.ts +1 -0
- package/dist/bun/register-bedrock.js +1 -0
- package/dist/bun/restore-sandbox-env.d.ts +12 -0
- package/dist/bun/restore-sandbox-env.js +1 -0
- package/dist/cli/args.d.ts +55 -0
- package/dist/cli/args.js +167 -0
- package/dist/cli/config-selector.d.ts +13 -0
- package/dist/cli/config-selector.js +1 -0
- package/dist/cli/file-processor.d.ts +14 -0
- package/dist/cli/file-processor.js +7 -0
- package/dist/cli/import-sessions.d.ts +34 -0
- package/dist/cli/import-sessions.js +6 -0
- package/dist/cli/initial-message.d.ts +17 -0
- package/dist/cli/initial-message.js +1 -0
- package/dist/cli/list-models.d.ts +8 -0
- package/dist/cli/list-models.js +2 -0
- package/dist/cli/openadapter-setup.d.ts +29 -0
- package/dist/cli/openadapter-setup.js +3 -0
- package/dist/cli/session-picker.d.ts +8 -0
- package/dist/cli/session-picker.js +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +2 -0
- package/dist/config.d.ts +92 -0
- package/dist/config.js +1 -0
- package/dist/core/agent-session-runtime.d.ts +116 -0
- package/dist/core/agent-session-runtime.js +1 -0
- package/dist/core/agent-session-services.d.ts +86 -0
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session.d.ts +747 -0
- package/dist/core/agent-session.js +32 -0
- package/dist/core/auth-guidance.d.ts +4 -0
- package/dist/core/auth-guidance.js +8 -0
- package/dist/core/auth-storage.d.ts +140 -0
- package/dist/core/auth-storage.js +1 -0
- package/dist/core/bash-executor.d.ts +31 -0
- package/dist/core/bash-executor.js +1 -0
- package/dist/core/compaction/branch-summarization.d.ts +89 -0
- package/dist/core/compaction/branch-summarization.js +38 -0
- package/dist/core/compaction/compaction.d.ts +120 -0
- package/dist/core/compaction/compaction.js +104 -0
- package/dist/core/compaction/index.d.ts +6 -0
- package/dist/core/compaction/index.js +1 -0
- package/dist/core/compaction/utils.d.ts +37 -0
- package/dist/core/compaction/utils.js +19 -0
- package/dist/core/defaults.d.ts +2 -0
- package/dist/core/defaults.js +1 -0
- package/dist/core/diagnostics.d.ts +14 -0
- package/dist/core/diagnostics.js +0 -0
- package/dist/core/event-bus.d.ts +8 -0
- package/dist/core/event-bus.js +1 -0
- package/dist/core/exec.d.ts +28 -0
- package/dist/core/exec.js +1 -0
- package/dist/core/export-html/ansi-to-html.d.ts +21 -0
- package/dist/core/export-html/ansi-to-html.js +1 -0
- package/dist/core/export-html/index.d.ts +36 -0
- package/dist/core/export-html/index.js +2 -0
- package/dist/core/export-html/template.css +1066 -0
- package/dist/core/export-html/template.html +55 -0
- package/dist/core/export-html/template.js +72 -0
- package/dist/core/export-html/tool-renderer.d.ts +33 -0
- package/dist/core/export-html/tool-renderer.js +1 -0
- package/dist/core/export-html/vendor/highlight.min.js +8 -0
- package/dist/core/export-html/vendor/marked.min.js +56 -0
- package/dist/core/extensions/index.d.ts +11 -0
- package/dist/core/extensions/index.js +1 -0
- package/dist/core/extensions/loader.d.ts +23 -0
- package/dist/core/extensions/loader.js +1 -0
- package/dist/core/extensions/runner.d.ts +160 -0
- package/dist/core/extensions/runner.js +1 -0
- package/dist/core/extensions/types.d.ts +1180 -0
- package/dist/core/extensions/types.js +1 -0
- package/dist/core/extensions/wrapper.d.ts +19 -0
- package/dist/core/extensions/wrapper.js +1 -0
- package/dist/core/footer-data-provider.d.ts +53 -0
- package/dist/core/footer-data-provider.js +1 -0
- package/dist/core/http-dispatcher.d.ts +20 -0
- package/dist/core/http-dispatcher.js +1 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.js +1 -0
- package/dist/core/keybindings.d.ts +352 -0
- package/dist/core/keybindings.js +1 -0
- package/dist/core/messages.d.ts +76 -0
- package/dist/core/messages.js +17 -0
- package/dist/core/model-registry.d.ts +149 -0
- package/dist/core/model-registry.js +9 -0
- package/dist/core/model-resolver.d.ts +109 -0
- package/dist/core/model-resolver.js +1 -0
- package/dist/core/output-guard.d.ts +6 -0
- package/dist/core/output-guard.js +1 -0
- package/dist/core/package-manager.d.ts +203 -0
- package/dist/core/package-manager.js +3 -0
- package/dist/core/prompt-templates.d.ts +51 -0
- package/dist/core/prompt-templates.js +2 -0
- package/dist/core/provider-attribution.d.ts +3 -0
- package/dist/core/provider-attribution.js +1 -0
- package/dist/core/provider-display-names.d.ts +1 -0
- package/dist/core/provider-display-names.js +1 -0
- package/dist/core/resolve-config-value.d.ts +30 -0
- package/dist/core/resolve-config-value.js +1 -0
- package/dist/core/resource-loader.d.ts +193 -0
- package/dist/core/resource-loader.js +1 -0
- package/dist/core/sdk.d.ts +108 -0
- package/dist/core/sdk.js +1 -0
- package/dist/core/session-cwd.d.ts +18 -0
- package/dist/core/session-cwd.js +7 -0
- package/dist/core/session-manager.d.ts +331 -0
- package/dist/core/session-manager.js +11 -0
- package/dist/core/settings-manager.d.ts +265 -0
- package/dist/core/settings-manager.js +1 -0
- package/dist/core/skills.d.ts +59 -0
- package/dist/core/skills.js +4 -0
- package/dist/core/slash-commands.d.ts +13 -0
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/source-info.d.ts +17 -0
- package/dist/core/source-info.js +1 -0
- package/dist/core/system-prompt.d.ts +27 -0
- package/dist/core/system-prompt.js +52 -0
- package/dist/core/telemetry.d.ts +2 -0
- package/dist/core/telemetry.js +1 -0
- package/dist/core/timings.d.ts +7 -0
- package/dist/core/timings.js +3 -0
- package/dist/core/tools/bash.d.ts +67 -0
- package/dist/core/tools/bash.js +18 -0
- package/dist/core/tools/edit-diff.d.ts +86 -0
- package/dist/core/tools/edit-diff.js +16 -0
- package/dist/core/tools/edit.d.ts +50 -0
- package/dist/core/tools/edit.js +2 -0
- package/dist/core/tools/file-mutation-queue.d.ts +5 -0
- package/dist/core/tools/file-mutation-queue.js +1 -0
- package/dist/core/tools/find.d.ts +34 -0
- package/dist/core/tools/find.js +13 -0
- package/dist/core/tools/grep.d.ts +36 -0
- package/dist/core/tools/grep.js +13 -0
- package/dist/core/tools/index.d.ts +39 -0
- package/dist/core/tools/index.js +1 -0
- package/dist/core/tools/ls.d.ts +36 -0
- package/dist/core/tools/ls.js +9 -0
- package/dist/core/tools/output-accumulator.d.ts +51 -0
- package/dist/core/tools/output-accumulator.js +4 -0
- package/dist/core/tools/path-utils.d.ts +9 -0
- package/dist/core/tools/path-utils.js +1 -0
- package/dist/core/tools/read.d.ts +34 -0
- package/dist/core/tools/read.js +22 -0
- package/dist/core/tools/render-utils.d.ts +23 -0
- package/dist/core/tools/render-utils.js +4 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +13 -0
- package/dist/core/tools/tool-definition-wrapper.js +1 -0
- package/dist/core/tools/truncate.d.ts +69 -0
- package/dist/core/tools/truncate.js +5 -0
- package/dist/core/tools/write.d.ts +25 -0
- package/dist/core/tools/write.js +13 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +1 -0
- package/dist/main.d.ts +11 -0
- package/dist/main.js +1 -0
- package/dist/migrations.d.ts +32 -0
- package/dist/migrations.js +8 -0
- package/dist/modes/index.d.ts +8 -0
- package/dist/modes/index.js +1 -0
- package/dist/modes/interactive/assets/clankolas.png +0 -0
- package/dist/modes/interactive/components/armin.d.ts +33 -0
- package/dist/modes/interactive/components/armin.js +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +19 -0
- package/dist/modes/interactive/components/assistant-message.js +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +33 -0
- package/dist/modes/interactive/components/bash-execution.js +13 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts +15 -0
- package/dist/modes/interactive/components/bordered-loader.js +1 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts +15 -0
- package/dist/modes/interactive/components/branch-summary-message.js +3 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +15 -0
- package/dist/modes/interactive/components/compaction-summary-message.js +3 -0
- package/dist/modes/interactive/components/config-selector.d.ts +70 -0
- package/dist/modes/interactive/components/config-selector.js +1 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts +13 -0
- package/dist/modes/interactive/components/countdown-timer.js +1 -0
- package/dist/modes/interactive/components/custom-editor.d.ts +20 -0
- package/dist/modes/interactive/components/custom-editor.js +1 -0
- package/dist/modes/interactive/components/custom-message.d.ts +19 -0
- package/dist/modes/interactive/components/custom-message.js +2 -0
- package/dist/modes/interactive/components/daxnuts.d.ts +22 -0
- package/dist/modes/interactive/components/daxnuts.js +1 -0
- package/dist/modes/interactive/components/diff.d.ts +11 -0
- package/dist/modes/interactive/components/diff.js +3 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts +14 -0
- package/dist/modes/interactive/components/dynamic-border.js +1 -0
- package/dist/modes/interactive/components/earendil-announcement.d.ts +4 -0
- package/dist/modes/interactive/components/earendil-announcement.js +1 -0
- package/dist/modes/interactive/components/extension-editor.d.ts +19 -0
- package/dist/modes/interactive/components/extension-editor.js +3 -0
- package/dist/modes/interactive/components/extension-input.d.ts +22 -0
- package/dist/modes/interactive/components/extension-input.js +2 -0
- package/dist/modes/interactive/components/extension-selector.d.ts +25 -0
- package/dist/modes/interactive/components/extension-selector.js +2 -0
- package/dist/modes/interactive/components/footer.d.ts +27 -0
- package/dist/modes/interactive/components/footer.js +1 -0
- package/dist/modes/interactive/components/index.d.ts +31 -0
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts +12 -0
- package/dist/modes/interactive/components/keybinding-hints.js +1 -0
- package/dist/modes/interactive/components/login-dialog.d.ts +51 -0
- package/dist/modes/interactive/components/login-dialog.js +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +46 -0
- package/dist/modes/interactive/components/model-selector.js +2 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts +30 -0
- package/dist/modes/interactive/components/oauth-selector.js +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +41 -0
- package/dist/modes/interactive/components/scoped-models-selector.js +1 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts +22 -0
- package/dist/modes/interactive/components/session-selector-search.js +1 -0
- package/dist/modes/interactive/components/session-selector.d.ts +95 -0
- package/dist/modes/interactive/components/session-selector.js +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +68 -0
- package/dist/modes/interactive/components/settings-selector.js +1 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts +9 -0
- package/dist/modes/interactive/components/show-images-selector.js +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +16 -0
- package/dist/modes/interactive/components/skill-invocation-message.js +3 -0
- package/dist/modes/interactive/components/theme-selector.d.ts +10 -0
- package/dist/modes/interactive/components/theme-selector.js +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +10 -0
- package/dist/modes/interactive/components/thinking-selector.js +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +62 -0
- package/dist/modes/interactive/components/tool-execution.js +4 -0
- package/dist/modes/interactive/components/tree-selector.d.ts +88 -0
- package/dist/modes/interactive/components/tree-selector.js +1 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts +29 -0
- package/dist/modes/interactive/components/user-message-selector.js +1 -0
- package/dist/modes/interactive/components/user-message.d.ts +9 -0
- package/dist/modes/interactive/components/user-message.js +1 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts +23 -0
- package/dist/modes/interactive/components/visual-truncate.js +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +417 -0
- package/dist/modes/interactive/interactive-mode.js +116 -0
- package/dist/modes/interactive/theme/dark.json +86 -0
- package/dist/modes/interactive/theme/light.json +85 -0
- package/dist/modes/interactive/theme/theme-schema.json +335 -0
- package/dist/modes/interactive/theme/theme.d.ts +101 -0
- package/dist/modes/interactive/theme/theme.js +18 -0
- package/dist/modes/print-mode.d.ts +27 -0
- package/dist/modes/print-mode.js +4 -0
- package/dist/modes/rpc/jsonl.d.ts +16 -0
- package/dist/modes/rpc/jsonl.js +3 -0
- package/dist/modes/rpc/rpc-client.d.ts +226 -0
- package/dist/modes/rpc/rpc-client.js +1 -0
- package/dist/modes/rpc/rpc-mode.d.ts +19 -0
- package/dist/modes/rpc/rpc-mode.js +1 -0
- package/dist/modes/rpc/rpc-types.d.ts +419 -0
- package/dist/modes/rpc/rpc-types.js +0 -0
- package/dist/package-manager-cli.d.ts +3 -0
- package/dist/package-manager-cli.js +49 -0
- package/dist/utils/ansi.d.ts +1 -0
- package/dist/utils/ansi.js +1 -0
- package/dist/utils/auto-update.d.ts +13 -0
- package/dist/utils/auto-update.js +1 -0
- package/dist/utils/changelog.d.ts +20 -0
- package/dist/utils/changelog.js +4 -0
- package/dist/utils/child-process.d.ts +14 -0
- package/dist/utils/child-process.js +1 -0
- package/dist/utils/clipboard-image.d.ts +10 -0
- package/dist/utils/clipboard-image.js +1 -0
- package/dist/utils/clipboard-native.d.ts +9 -0
- package/dist/utils/clipboard-native.js +1 -0
- package/dist/utils/clipboard.d.ts +1 -0
- package/dist/utils/clipboard.js +1 -0
- package/dist/utils/deprecation.d.ts +3 -0
- package/dist/utils/deprecation.js +1 -0
- package/dist/utils/exif-orientation.d.ts +4 -0
- package/dist/utils/exif-orientation.js +1 -0
- package/dist/utils/frontmatter.d.ts +7 -0
- package/dist/utils/frontmatter.js +4 -0
- package/dist/utils/fs-watch.d.ts +4 -0
- package/dist/utils/fs-watch.js +1 -0
- package/dist/utils/git.d.ts +25 -0
- package/dist/utils/git.js +1 -0
- package/dist/utils/html.d.ts +6 -0
- package/dist/utils/html.js +1 -0
- package/dist/utils/image-convert.d.ts +8 -0
- package/dist/utils/image-convert.js +1 -0
- package/dist/utils/image-resize-core.d.ts +29 -0
- package/dist/utils/image-resize-core.js +1 -0
- package/dist/utils/image-resize-worker.d.ts +1 -0
- package/dist/utils/image-resize-worker.js +1 -0
- package/dist/utils/image-resize.d.ts +15 -0
- package/dist/utils/image-resize.js +1 -0
- package/dist/utils/json.d.ts +2 -0
- package/dist/utils/json.js +1 -0
- package/dist/utils/koda-user-agent.d.ts +1 -0
- package/dist/utils/koda-user-agent.js +1 -0
- package/dist/utils/mime.d.ts +2 -0
- package/dist/utils/mime.js +1 -0
- package/dist/utils/paths.d.ts +30 -0
- package/dist/utils/paths.js +1 -0
- package/dist/utils/photon.d.ts +20 -0
- package/dist/utils/photon.js +1 -0
- package/dist/utils/shell.d.ts +29 -0
- package/dist/utils/shell.js +8 -0
- package/dist/utils/sleep.d.ts +4 -0
- package/dist/utils/sleep.js +1 -0
- package/dist/utils/syntax-highlight.d.ts +11 -0
- package/dist/utils/syntax-highlight.js +2 -0
- package/dist/utils/tools-manager.d.ts +2 -0
- package/dist/utils/tools-manager.js +1 -0
- package/dist/utils/version-check.d.ts +14 -0
- package/dist/utils/version-check.js +1 -0
- package/dist/utils/windows-self-update.d.ts +2 -0
- package/dist/utils/windows-self-update.js +1 -0
- package/docs/compaction.md +394 -0
- package/docs/custom-provider.md +736 -0
- package/docs/development.md +71 -0
- package/docs/docs.json +148 -0
- package/docs/extensions.md +2626 -0
- package/docs/images/doom-extension.png +0 -0
- package/docs/images/exy.png +0 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/images/tree-view.png +0 -0
- package/docs/index.md +80 -0
- package/docs/json.md +82 -0
- package/docs/keybindings.md +197 -0
- package/docs/models.md +493 -0
- package/docs/packages.md +226 -0
- package/docs/prompt-templates.md +88 -0
- package/docs/providers.md +253 -0
- package/docs/quickstart.md +165 -0
- package/docs/rpc.md +1408 -0
- package/docs/sdk.md +1137 -0
- package/docs/session-format.md +412 -0
- package/docs/sessions.md +145 -0
- package/docs/settings.md +281 -0
- package/docs/shell-aliases.md +13 -0
- package/docs/skills.md +231 -0
- package/docs/terminal-setup.md +114 -0
- package/docs/termux.md +127 -0
- package/docs/themes.md +295 -0
- package/docs/tmux.md +61 -0
- package/docs/tui.md +927 -0
- package/docs/usage.md +288 -0
- package/docs/windows.md +17 -0
- package/npm-shrinkwrap.json +1792 -0
- package/openadapter/extensions/koda-ask.js +12 -0
- package/openadapter/extensions/koda-bg.js +14 -0
- package/openadapter/extensions/koda-commands.mjs +15 -0
- package/openadapter/extensions/koda-help.js +8 -0
- package/openadapter/extensions/koda-memory.js +16 -0
- package/openadapter/extensions/koda-status.js +1 -0
- package/openadapter/extensions/koda-todo.js +4 -0
- package/openadapter/extensions/koda-vision.js +4 -0
- package/openadapter/extensions/koda-web.js +7 -0
- package/openadapter/setup.mjs +173 -0
- package/openadapter/skills/code-review/SKILL.md +22 -0
- package/openadapter/skills/debugging/SKILL.md +28 -0
- package/openadapter/skills/frontend/SKILL.md +38 -0
- package/package.json +108 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context compaction for long sessions.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions for compaction logic. The session manager handles I/O,
|
|
5
|
+
* and after compaction the session is reloaded.
|
|
6
|
+
*/
|
|
7
|
+
import type { AgentMessage, StreamFn, ThinkingLevel } from "@openadapter/koda-agent-core";
|
|
8
|
+
import type { Model, Usage } from "@openadapter/koda-ai";
|
|
9
|
+
import { type SessionEntry } from "../session-manager.ts";
|
|
10
|
+
import { type FileOperations } from "./utils.ts";
|
|
11
|
+
/** Details stored in CompactionEntry.details for file tracking */
|
|
12
|
+
export interface CompactionDetails {
|
|
13
|
+
readFiles: string[];
|
|
14
|
+
modifiedFiles: string[];
|
|
15
|
+
}
|
|
16
|
+
/** Result from compact() - SessionManager adds uuid/parentUuid when saving */
|
|
17
|
+
export interface CompactionResult<T = unknown> {
|
|
18
|
+
summary: string;
|
|
19
|
+
firstKeptEntryId: string;
|
|
20
|
+
tokensBefore: number;
|
|
21
|
+
/** Extension-specific data (e.g., ArtifactIndex, version markers for structured compaction) */
|
|
22
|
+
details?: T;
|
|
23
|
+
}
|
|
24
|
+
export interface CompactionSettings {
|
|
25
|
+
enabled: boolean;
|
|
26
|
+
reserveTokens: number;
|
|
27
|
+
keepRecentTokens: number;
|
|
28
|
+
}
|
|
29
|
+
export declare const DEFAULT_COMPACTION_SETTINGS: CompactionSettings;
|
|
30
|
+
/**
|
|
31
|
+
* Calculate total context tokens from usage.
|
|
32
|
+
* Uses the native totalTokens field when available, falls back to computing from components.
|
|
33
|
+
*/
|
|
34
|
+
export declare function calculateContextTokens(usage: Usage): number;
|
|
35
|
+
/**
|
|
36
|
+
* Find the last non-aborted assistant message usage from session entries.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getLastAssistantUsage(entries: SessionEntry[]): Usage | undefined;
|
|
39
|
+
export interface ContextUsageEstimate {
|
|
40
|
+
tokens: number;
|
|
41
|
+
usageTokens: number;
|
|
42
|
+
trailingTokens: number;
|
|
43
|
+
lastUsageIndex: number | null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Estimate context tokens from messages, using the last assistant usage when available.
|
|
47
|
+
* If there are messages after the last usage, estimate their tokens with estimateTokens.
|
|
48
|
+
*/
|
|
49
|
+
export declare function estimateContextTokens(messages: AgentMessage[]): ContextUsageEstimate;
|
|
50
|
+
/**
|
|
51
|
+
* Check if compaction should trigger based on context usage.
|
|
52
|
+
*/
|
|
53
|
+
export declare function shouldCompact(contextTokens: number, contextWindow: number, settings: CompactionSettings): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Estimate token count for a message using chars/4 heuristic.
|
|
56
|
+
* This is conservative (overestimates tokens).
|
|
57
|
+
*/
|
|
58
|
+
export declare function estimateTokens(message: AgentMessage): number;
|
|
59
|
+
/**
|
|
60
|
+
* Find the user message (or bashExecution) that starts the turn containing the given entry index.
|
|
61
|
+
* Returns -1 if no turn start found before the index.
|
|
62
|
+
* BashExecutionMessage is treated like a user message for turn boundaries.
|
|
63
|
+
*/
|
|
64
|
+
export declare function findTurnStartIndex(entries: SessionEntry[], entryIndex: number, startIndex: number): number;
|
|
65
|
+
export interface CutPointResult {
|
|
66
|
+
/** Index of first entry to keep */
|
|
67
|
+
firstKeptEntryIndex: number;
|
|
68
|
+
/** Index of user message that starts the turn being split, or -1 if not splitting */
|
|
69
|
+
turnStartIndex: number;
|
|
70
|
+
/** Whether this cut splits a turn (cut point is not a user message) */
|
|
71
|
+
isSplitTurn: boolean;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Find the cut point in session entries that keeps approximately `keepRecentTokens`.
|
|
75
|
+
*
|
|
76
|
+
* Algorithm: Walk backwards from newest, accumulating estimated message sizes.
|
|
77
|
+
* Stop when we've accumulated >= keepRecentTokens. Cut at that point.
|
|
78
|
+
*
|
|
79
|
+
* Can cut at user OR assistant messages (never tool results). When cutting at an
|
|
80
|
+
* assistant message with tool calls, its tool results come after and will be kept.
|
|
81
|
+
*
|
|
82
|
+
* Returns CutPointResult with:
|
|
83
|
+
* - firstKeptEntryIndex: the entry index to start keeping from
|
|
84
|
+
* - turnStartIndex: if cutting mid-turn, the user message that started that turn
|
|
85
|
+
* - isSplitTurn: whether we're cutting in the middle of a turn
|
|
86
|
+
*
|
|
87
|
+
* Only considers entries between `startIndex` and `endIndex` (exclusive).
|
|
88
|
+
*/
|
|
89
|
+
export declare function findCutPoint(entries: SessionEntry[], startIndex: number, endIndex: number, keepRecentTokens: number): CutPointResult;
|
|
90
|
+
/**
|
|
91
|
+
* Generate a summary of the conversation using the LLM.
|
|
92
|
+
* If previousSummary is provided, uses the update prompt to merge.
|
|
93
|
+
*/
|
|
94
|
+
export declare function generateSummary(currentMessages: AgentMessage[], model: Model<any>, reserveTokens: number, apiKey: string | undefined, headers?: Record<string, string>, signal?: AbortSignal, customInstructions?: string, previousSummary?: string, thinkingLevel?: ThinkingLevel, streamFn?: StreamFn): Promise<string>;
|
|
95
|
+
export interface CompactionPreparation {
|
|
96
|
+
/** UUID of first entry to keep */
|
|
97
|
+
firstKeptEntryId: string;
|
|
98
|
+
/** Messages that will be summarized and discarded */
|
|
99
|
+
messagesToSummarize: AgentMessage[];
|
|
100
|
+
/** Messages that will be turned into turn prefix summary (if splitting) */
|
|
101
|
+
turnPrefixMessages: AgentMessage[];
|
|
102
|
+
/** Whether this is a split turn (cut point in middle of turn) */
|
|
103
|
+
isSplitTurn: boolean;
|
|
104
|
+
tokensBefore: number;
|
|
105
|
+
/** Summary from previous compaction, for iterative update */
|
|
106
|
+
previousSummary?: string;
|
|
107
|
+
/** File operations extracted from messagesToSummarize */
|
|
108
|
+
fileOps: FileOperations;
|
|
109
|
+
/** Compaction settions from settings.jsonl */
|
|
110
|
+
settings: CompactionSettings;
|
|
111
|
+
}
|
|
112
|
+
export declare function prepareCompaction(pathEntries: SessionEntry[], settings: CompactionSettings): CompactionPreparation | undefined;
|
|
113
|
+
/**
|
|
114
|
+
* Generate summaries for compaction using prepared data.
|
|
115
|
+
* Returns CompactionResult - SessionManager adds uuid/parentUuid when saving.
|
|
116
|
+
*
|
|
117
|
+
* @param preparation - Pre-calculated preparation from prepareCompaction()
|
|
118
|
+
* @param customInstructions - Optional custom focus for the summary
|
|
119
|
+
*/
|
|
120
|
+
export declare function compact(preparation: CompactionPreparation, model: Model<any>, apiKey: string | undefined, headers?: Record<string, string>, customInstructions?: string, signal?: AbortSignal, thinkingLevel?: ThinkingLevel, streamFn?: StreamFn): Promise<CompactionResult>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
var _=Object.defineProperty;var u=(e,t)=>_(e,"name",{value:t,configurable:!0});import{completeSimple as U}from"@openadapter/koda-ai";import{convertToLlm as I,createBranchSummaryMessage as F,createCompactionSummaryMessage as N,createCustomMessage as D}from"../messages.js";import{buildSessionContext as K}from"../session-manager.js";import{computeFileLists as z,createFileOps as $,extractFileOpsFromMessage as P,formatFileOperations as B,SUMMARIZATION_SYSTEM_PROMPT as v,serializeConversation as w}from"./utils.js";function V(e,t,n){const s=$();if(n>=0){const o=t[n];if(!o.fromHook&&o.details){const r=o.details;if(Array.isArray(r.readFiles))for(const a of r.readFiles)s.read.add(a);if(Array.isArray(r.modifiedFiles))for(const a of r.modifiedFiles)s.edited.add(a)}}for(const o of e)P(o,s);return s}u(V,"extractFileOperations");function X(e){if(e.type==="message")return e.message;if(e.type==="custom_message")return D(e.customType,e.content,e.display,e.details,e.timestamp);if(e.type==="branch_summary")return F(e.summary,e.fromId,e.timestamp);if(e.type==="compaction")return N(e.summary,e.tokensBefore,e.timestamp)}u(X,"getMessageFromEntry");function M(e){if(e.type!=="compaction")return X(e)}u(M,"getMessageFromEntryForCompaction");const ie={enabled:!0,reserveTokens:16384,keepRecentTokens:2e4};function G(e){return e.totalTokens||e.input+e.output+e.cacheRead+e.cacheWrite}u(G,"calculateContextTokens");function b(e){if(e.role==="assistant"&&"usage"in e){const t=e;if(t.stopReason!=="aborted"&&t.stopReason!=="error"&&t.usage)return t.usage}}u(b,"getAssistantUsage");function ae(e){for(let t=e.length-1;t>=0;t--){const n=e[t];if(n.type==="message"){const s=b(n.message);if(s)return s}}}u(ae,"getLastAssistantUsage");function L(e){for(let t=e.length-1;t>=0;t--){const n=b(e[t]);if(n)return{usage:n,index:t}}}u(L,"getLastAssistantUsageInfo");function W(e){const t=L(e);if(!t){let o=0;for(const r of e)o+=S(r);return{tokens:o,usageTokens:0,trailingTokens:o,lastUsageIndex:null}}const n=G(t.usage);let s=0;for(let o=t.index+1;o<e.length;o++)s+=S(e[o]);return{tokens:n+s,usageTokens:n,trailingTokens:s,lastUsageIndex:t.index}}u(W,"estimateContextTokens");function ce(e,t,n){return n.enabled?e>t-n.reserveTokens:!1}u(ce,"shouldCompact");const Z=4800;function C(e){if(typeof e=="string")return e.length;let t=0;for(const n of e)n.type==="text"&&n.text?t+=n.text.length:n.type==="image"&&(t+=Z);return t}u(C,"estimateTextAndImageContentChars");function S(e){let t=0;switch(e.role){case"user":return t=C(e.content),Math.ceil(t/4);case"assistant":{const n=e;for(const s of n.content)s.type==="text"?t+=s.text.length:s.type==="thinking"?t+=s.thinking.length:s.type==="toolCall"&&(t+=s.name.length+JSON.stringify(s.arguments).length);return Math.ceil(t/4)}case"custom":case"toolResult":return t=C(e.content),Math.ceil(t/4);case"bashExecution":return t=e.command.length+e.output.length,Math.ceil(t/4);case"branchSummary":case"compactionSummary":return t=e.summary.length,Math.ceil(t/4)}return 0}u(S,"estimateTokens");function Y(e,t,n){const s=[];for(let o=t;o<n;o++){const r=e[o];switch(r.type){case"message":{switch(r.message.role){case"bashExecution":case"custom":case"branchSummary":case"compactionSummary":case"user":case"assistant":s.push(o);break;case"toolResult":break}break}case"thinking_level_change":case"model_change":case"compaction":case"branch_summary":case"custom":case"custom_message":case"label":case"session_info":break}(r.type==="branch_summary"||r.type==="custom_message")&&s.push(o)}return s}u(Y,"findValidCutPoints");function j(e,t,n){for(let s=t;s>=n;s--){const o=e[s];if(o.type==="branch_summary"||o.type==="custom_message")return s;if(o.type==="message"){const r=o.message.role;if(r==="user"||r==="bashExecution")return s}}return-1}u(j,"findTurnStartIndex");function q(e,t,n,s){const o=Y(e,t,n);if(o.length===0)return{firstKeptEntryIndex:t,turnStartIndex:-1,isSplitTurn:!1};let r=0,a=o[0];for(let m=n-1;m>=t;m--){const p=e[m];if(p.type!=="message")continue;const x=S(p.message);if(r+=x,r>=s){for(let f=0;f<o.length;f++)if(o[f]>=m){a=o[f];break}break}}for(;a>t;){const m=e[a-1];if(m.type==="compaction"||m.type==="message")break;a--}const c=e[a],d=c.type==="message"&&c.message.role==="user",g=d?-1:j(e,a,t);return{firstKeptEntryIndex:a,turnStartIndex:g,isSplitTurn:!d&&g!==-1}}u(q,"findCutPoint");const H=`The messages above are a conversation to summarize. Create a structured context checkpoint summary that another LLM will use to continue the work.
|
|
2
|
+
|
|
3
|
+
Use this EXACT format:
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
[What is the user trying to accomplish? Can be multiple items if the session covers different tasks.]
|
|
7
|
+
|
|
8
|
+
## Constraints & Preferences
|
|
9
|
+
- [Any constraints, preferences, or requirements mentioned by user]
|
|
10
|
+
- [Or "(none)" if none were mentioned]
|
|
11
|
+
|
|
12
|
+
## Progress
|
|
13
|
+
### Done
|
|
14
|
+
- [x] [Completed tasks/changes]
|
|
15
|
+
|
|
16
|
+
### In Progress
|
|
17
|
+
- [ ] [Current work]
|
|
18
|
+
|
|
19
|
+
### Blocked
|
|
20
|
+
- [Issues preventing progress, if any]
|
|
21
|
+
|
|
22
|
+
## Key Decisions
|
|
23
|
+
- **[Decision]**: [Brief rationale]
|
|
24
|
+
|
|
25
|
+
## Next Steps
|
|
26
|
+
1. [Ordered list of what should happen next]
|
|
27
|
+
|
|
28
|
+
## Critical Context
|
|
29
|
+
- [Any data, examples, or references needed to continue]
|
|
30
|
+
- [Or "(none)" if not applicable]
|
|
31
|
+
|
|
32
|
+
Keep each section concise. Preserve exact file paths, function names, and error messages.`,J=`The messages above are NEW conversation messages to incorporate into the existing summary provided in <previous-summary> tags.
|
|
33
|
+
|
|
34
|
+
Update the existing structured summary with new information. RULES:
|
|
35
|
+
- PRESERVE all existing information from the previous summary
|
|
36
|
+
- ADD new progress, decisions, and context from the new messages
|
|
37
|
+
- UPDATE the Progress section: move items from "In Progress" to "Done" when completed
|
|
38
|
+
- UPDATE "Next Steps" based on what was accomplished
|
|
39
|
+
- PRESERVE exact file paths, function names, and error messages
|
|
40
|
+
- If something is no longer relevant, you may remove it
|
|
41
|
+
|
|
42
|
+
Use this EXACT format:
|
|
43
|
+
|
|
44
|
+
## Goal
|
|
45
|
+
[Preserve existing goals, add new ones if the task expanded]
|
|
46
|
+
|
|
47
|
+
## Constraints & Preferences
|
|
48
|
+
- [Preserve existing, add new ones discovered]
|
|
49
|
+
|
|
50
|
+
## Progress
|
|
51
|
+
### Done
|
|
52
|
+
- [x] [Include previously done items AND newly completed items]
|
|
53
|
+
|
|
54
|
+
### In Progress
|
|
55
|
+
- [ ] [Current work - update based on progress]
|
|
56
|
+
|
|
57
|
+
### Blocked
|
|
58
|
+
- [Current blockers - remove if resolved]
|
|
59
|
+
|
|
60
|
+
## Key Decisions
|
|
61
|
+
- **[Decision]**: [Brief rationale] (preserve all previous, add new)
|
|
62
|
+
|
|
63
|
+
## Next Steps
|
|
64
|
+
1. [Update based on current state]
|
|
65
|
+
|
|
66
|
+
## Critical Context
|
|
67
|
+
- [Preserve important context, add new if needed]
|
|
68
|
+
|
|
69
|
+
Keep each section concise. Preserve exact file paths, function names, and error messages.`;function E(e,t,n,s,o,r){const a={maxTokens:t,signal:o,apiKey:n,headers:s};return e.reasoning&&r&&r!=="off"&&(a.reasoning=r),a}u(E,"createSummarizationOptions");async function A(e,t,n,s){return s?(await s(e,t,n)).result():U(e,t,n)}u(A,"completeSummarization");async function R(e,t,n,s,o,r,a,c,d,g){const m=Math.min(Math.floor(.8*n),t.maxTokens>0?t.maxTokens:Number.POSITIVE_INFINITY);let p=c?J:H;a&&(p=`${p}
|
|
70
|
+
|
|
71
|
+
Additional focus: ${a}`);const x=I(e);let i=`<conversation>
|
|
72
|
+
${w(x)}
|
|
73
|
+
</conversation>
|
|
74
|
+
|
|
75
|
+
`;c&&(i+=`<previous-summary>
|
|
76
|
+
${c}
|
|
77
|
+
</previous-summary>
|
|
78
|
+
|
|
79
|
+
`),i+=p;const l=[{role:"user",content:[{type:"text",text:i}],timestamp:Date.now()}],h=E(t,m,s,o,r,d),y=await A(t,{systemPrompt:v,messages:l},h,g);if(y.stopReason==="error")throw new Error(`Summarization failed: ${y.errorMessage||"Unknown error"}`);return y.content.filter(T=>T.type==="text").map(T=>T.text).join(`
|
|
80
|
+
`)}u(R,"generateSummary");function ue(e,t){if(e.length>0&&e[e.length-1].type==="compaction")return;let n=-1;for(let i=e.length-1;i>=0;i--)if(e[i].type==="compaction"){n=i;break}let s,o=0;if(n>=0){const i=e[n];s=i.summary;const l=e.findIndex(h=>h.id===i.firstKeptEntryId);o=l>=0?l:n+1}const r=e.length,a=W(K(e).messages).tokens,c=q(e,o,r,t.keepRecentTokens),d=e[c.firstKeptEntryIndex];if(!d?.id)return;const g=d.id,m=c.isSplitTurn?c.turnStartIndex:c.firstKeptEntryIndex,p=[];for(let i=o;i<m;i++){const l=M(e[i]);l&&p.push(l)}const x=[];if(c.isSplitTurn)for(let i=c.turnStartIndex;i<c.firstKeptEntryIndex;i++){const l=M(e[i]);l&&x.push(l)}const f=V(p,e,n);if(c.isSplitTurn)for(const i of x)P(i,f);return{firstKeptEntryId:g,messagesToSummarize:p,turnPrefixMessages:x,isSplitTurn:c.isSplitTurn,tokensBefore:a,previousSummary:s,fileOps:f,settings:t}}u(ue,"prepareCompaction");const Q=`This is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.
|
|
81
|
+
|
|
82
|
+
Summarize the prefix to provide context for the retained suffix:
|
|
83
|
+
|
|
84
|
+
## Original Request
|
|
85
|
+
[What did the user ask for in this turn?]
|
|
86
|
+
|
|
87
|
+
## Early Progress
|
|
88
|
+
- [Key decisions and work done in the prefix]
|
|
89
|
+
|
|
90
|
+
## Context for Suffix
|
|
91
|
+
- [Information needed to understand the retained recent work]
|
|
92
|
+
|
|
93
|
+
Be concise. Focus on what's needed to understand the kept suffix.`;async function me(e,t,n,s,o,r,a,c){const{firstKeptEntryId:d,messagesToSummarize:g,turnPrefixMessages:m,isSplitTurn:p,tokensBefore:x,previousSummary:f,fileOps:i,settings:l}=e;let h;if(p&&m.length>0){const[T,O]=await Promise.all([g.length>0?R(g,t,l.reserveTokens,n,s,r,o,f,a,c):Promise.resolve("No prior history."),ee(m,t,l.reserveTokens,n,s,r,a,c)]);h=`${T}
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
**Turn Context (split turn):**
|
|
98
|
+
|
|
99
|
+
${O}`}else h=await R(g,t,l.reserveTokens,n,s,r,o,f,a,c);const{readFiles:y,modifiedFiles:k}=z(i);if(h+=B(y,k),!d)throw new Error("First kept entry has no UUID - session may need migration");return{summary:h,firstKeptEntryId:d,tokensBefore:x,details:{readFiles:y,modifiedFiles:k}}}u(me,"compact");async function ee(e,t,n,s,o,r,a,c){const d=Math.min(Math.floor(.5*n),t.maxTokens>0?t.maxTokens:Number.POSITIVE_INFINITY),g=I(e),x=[{role:"user",content:[{type:"text",text:`<conversation>
|
|
100
|
+
${w(g)}
|
|
101
|
+
</conversation>
|
|
102
|
+
|
|
103
|
+
${Q}`}],timestamp:Date.now()}],f=await A(t,{systemPrompt:v,messages:x},E(t,d,s,o,r,a),c);if(f.stopReason==="error")throw new Error(`Turn prefix summarization failed: ${f.errorMessage||"Unknown error"}`);return f.content.filter(i=>i.type==="text").map(i=>i.text).join(`
|
|
104
|
+
`)}u(ee,"generateTurnPrefixSummary");export{ie as DEFAULT_COMPACTION_SETTINGS,G as calculateContextTokens,me as compact,W as estimateContextTokens,S as estimateTokens,q as findCutPoint,j as findTurnStartIndex,R as generateSummary,ae as getLastAssistantUsage,ue as prepareCompaction,ce as shouldCompact};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./branch-summarization.js";export*from"./compaction.js";export*from"./utils.js";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for compaction and branch summarization.
|
|
3
|
+
*/
|
|
4
|
+
import type { AgentMessage } from "@openadapter/koda-agent-core";
|
|
5
|
+
import type { Message } from "@openadapter/koda-ai";
|
|
6
|
+
export interface FileOperations {
|
|
7
|
+
read: Set<string>;
|
|
8
|
+
written: Set<string>;
|
|
9
|
+
edited: Set<string>;
|
|
10
|
+
}
|
|
11
|
+
export declare function createFileOps(): FileOperations;
|
|
12
|
+
/**
|
|
13
|
+
* Extract file operations from tool calls in an assistant message.
|
|
14
|
+
*/
|
|
15
|
+
export declare function extractFileOpsFromMessage(message: AgentMessage, fileOps: FileOperations): void;
|
|
16
|
+
/**
|
|
17
|
+
* Compute final file lists from file operations.
|
|
18
|
+
* Returns readFiles (files only read, not modified) and modifiedFiles.
|
|
19
|
+
*/
|
|
20
|
+
export declare function computeFileLists(fileOps: FileOperations): {
|
|
21
|
+
readFiles: string[];
|
|
22
|
+
modifiedFiles: string[];
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Format file operations as XML tags for summary.
|
|
26
|
+
*/
|
|
27
|
+
export declare function formatFileOperations(readFiles: string[], modifiedFiles: string[]): string;
|
|
28
|
+
/**
|
|
29
|
+
* Serialize LLM messages to text for summarization.
|
|
30
|
+
* This prevents the model from treating it as a conversation to continue.
|
|
31
|
+
* Call convertToLlm() first to handle custom message types.
|
|
32
|
+
*
|
|
33
|
+
* Tool results are truncated to keep the summarization request within
|
|
34
|
+
* reasonable token budgets. Full content is not needed for summarization.
|
|
35
|
+
*/
|
|
36
|
+
export declare function serializeConversation(messages: Message[]): string;
|
|
37
|
+
export declare const SUMMARIZATION_SYSTEM_PROMPT = "You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
var d=Object.defineProperty;var r=(e,n)=>d(e,"name",{value:n,configurable:!0});function m(){return{read:new Set,written:new Set,edited:new Set}}r(m,"createFileOps");function y(e,n){if(e.role==="assistant"&&!(!("content"in e)||!Array.isArray(e.content)))for(const t of e.content){if(typeof t!="object"||t===null||!("type"in t)||t.type!=="toolCall"||!("arguments"in t)||!("name"in t))continue;const i=t.arguments;if(!i)continue;const o=typeof i.path=="string"?i.path:void 0;if(o)switch(t.name){case"read":n.read.add(o);break;case"write":n.written.add(o);break;case"edit":n.edited.add(o);break}}}r(y,"extractFileOpsFromMessage");function $(e){const n=new Set([...e.edited,...e.written]),t=[...e.read].filter(o=>!n.has(o)).sort(),i=[...n].sort();return{readFiles:t,modifiedFiles:i}}r($,"computeFileLists");function j(e,n){const t=[];return e.length>0&&t.push(`<read-files>
|
|
2
|
+
${e.join(`
|
|
3
|
+
`)}
|
|
4
|
+
</read-files>`),n.length>0&&t.push(`<modified-files>
|
|
5
|
+
${n.join(`
|
|
6
|
+
`)}
|
|
7
|
+
</modified-files>`),t.length===0?"":`
|
|
8
|
+
|
|
9
|
+
${t.join(`
|
|
10
|
+
|
|
11
|
+
`)}`}r(j,"formatFileOperations");const p=2e3;function h(e,n){if(e.length<=n)return e;const t=e.length-n;return`${e.slice(0,n)}
|
|
12
|
+
|
|
13
|
+
[... ${t} more characters truncated]`}r(h,"truncateForSummary");function S(e){const n=[];for(const t of e)if(t.role==="user"){const i=typeof t.content=="string"?t.content:t.content.filter(o=>o.type==="text").map(o=>o.text).join("");i&&n.push(`[User]: ${i}`)}else if(t.role==="assistant"){const i=[],o=[],a=[];for(const s of t.content)if(s.type==="text")i.push(s.text);else if(s.type==="thinking")o.push(s.thinking);else if(s.type==="toolCall"){const c=s.arguments,u=Object.entries(c).map(([f,l])=>`${f}=${JSON.stringify(l)}`).join(", ");a.push(`${s.name}(${u})`)}o.length>0&&n.push(`[Assistant thinking]: ${o.join(`
|
|
14
|
+
`)}`),i.length>0&&n.push(`[Assistant]: ${i.join(`
|
|
15
|
+
`)}`),a.length>0&&n.push(`[Assistant tool calls]: ${a.join("; ")}`)}else if(t.role==="toolResult"){const i=t.content.filter(o=>o.type==="text").map(o=>o.text).join("");i&&n.push(`[Tool result]: ${h(i,p)}`)}return n.join(`
|
|
16
|
+
|
|
17
|
+
`)}r(S,"serializeConversation");const w=`You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.
|
|
18
|
+
|
|
19
|
+
Do NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.`;export{w as SUMMARIZATION_SYSTEM_PROMPT,$ as computeFileLists,m as createFileOps,y as extractFileOpsFromMessage,j as formatFileOperations,S as serializeConversation};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const E="medium";export{E as DEFAULT_THINKING_LEVEL};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ResourceCollision {
|
|
2
|
+
resourceType: "extension" | "skill" | "prompt" | "theme";
|
|
3
|
+
name: string;
|
|
4
|
+
winnerPath: string;
|
|
5
|
+
loserPath: string;
|
|
6
|
+
winnerSource?: string;
|
|
7
|
+
loserSource?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ResourceDiagnostic {
|
|
10
|
+
type: "warning" | "error" | "collision";
|
|
11
|
+
message: string;
|
|
12
|
+
path?: string;
|
|
13
|
+
collision?: ResourceCollision;
|
|
14
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface EventBus {
|
|
2
|
+
emit(channel: string, data: unknown): void;
|
|
3
|
+
on(channel: string, handler: (data: unknown) => void): () => void;
|
|
4
|
+
}
|
|
5
|
+
export interface EventBusController extends EventBus {
|
|
6
|
+
clear(): void;
|
|
7
|
+
}
|
|
8
|
+
export declare function createEventBus(): EventBusController;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var a=Object.defineProperty;var t=(r,e)=>a(r,"name",{value:e,configurable:!0});import{EventEmitter as c}from"node:events";function l(){const r=new c;return{emit:t((e,o)=>{r.emit(e,o)},"emit"),on:t((e,o)=>{const n=t(async i=>{try{await o(i)}catch(s){console.error(`Event handler error (${e}):`,s)}},"safeHandler");return r.on(e,n),()=>r.off(e,n)},"on"),clear:t(()=>{r.removeAllListeners()},"clear")}}t(l,"createEventBus");export{l as createEventBus};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared command execution utilities for extensions and custom tools.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Options for executing shell commands.
|
|
6
|
+
*/
|
|
7
|
+
export interface ExecOptions {
|
|
8
|
+
/** AbortSignal to cancel the command */
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
/** Timeout in milliseconds */
|
|
11
|
+
timeout?: number;
|
|
12
|
+
/** Working directory */
|
|
13
|
+
cwd?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Result of executing a shell command.
|
|
17
|
+
*/
|
|
18
|
+
export interface ExecResult {
|
|
19
|
+
stdout: string;
|
|
20
|
+
stderr: string;
|
|
21
|
+
code: number;
|
|
22
|
+
killed: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Execute a shell command and return stdout/stderr/code.
|
|
26
|
+
* Supports timeout and abort signal.
|
|
27
|
+
*/
|
|
28
|
+
export declare function execCommand(command: string, args: string[], cwd: string, options?: ExecOptions): Promise<ExecResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var u=Object.defineProperty;var m=(n,o)=>u(n,"name",{value:o,configurable:!0});import{spawn as g}from"node:child_process";import{waitForChildProcess as k}from"../utils/child-process.js";async function h(n,o,f,e){return new Promise(c=>{const t=g(n,o,{cwd:f,shell:!1,stdio:["ignore","pipe","pipe"]});let s="",d="",a=!1,r;const l=m(()=>{a||(a=!0,t.kill("SIGTERM"),setTimeout(()=>{t.killed||t.kill("SIGKILL")},5e3))},"killProcess");e?.signal&&(e.signal.aborted?l():e.signal.addEventListener("abort",l,{once:!0})),e?.timeout&&e.timeout>0&&(r=setTimeout(()=>{l()},e.timeout)),t.stdout?.on("data",i=>{s+=i.toString()}),t.stderr?.on("data",i=>{d+=i.toString()}),k(t).then(i=>{r&&clearTimeout(r),e?.signal&&e.signal.removeEventListener("abort",l),c({stdout:s,stderr:d,code:i??0,killed:a})}).catch(i=>{r&&clearTimeout(r),e?.signal&&e.signal.removeEventListener("abort",l),c({stdout:s,stderr:d,code:1,killed:a})})})}m(h,"execCommand");export{h as execCommand};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ANSI escape code to HTML converter.
|
|
3
|
+
*
|
|
4
|
+
* Converts terminal ANSI color/style codes to HTML with inline styles.
|
|
5
|
+
* Supports:
|
|
6
|
+
* - Standard foreground colors (30-37) and bright variants (90-97)
|
|
7
|
+
* - Standard background colors (40-47) and bright variants (100-107)
|
|
8
|
+
* - 256-color palette (38;5;N and 48;5;N)
|
|
9
|
+
* - RGB true color (38;2;R;G;B and 48;2;R;G;B)
|
|
10
|
+
* - Text styles: bold (1), dim (2), italic (3), underline (4)
|
|
11
|
+
* - Reset (0)
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Convert ANSI-escaped text to HTML with inline styles.
|
|
15
|
+
*/
|
|
16
|
+
export declare function ansiToHtml(text: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Convert array of ANSI-escaped lines to HTML.
|
|
19
|
+
* Each line is wrapped in a div element.
|
|
20
|
+
*/
|
|
21
|
+
export declare function ansiLinesToHtml(lines: string[]): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var p=Object.defineProperty;var o=(n,e)=>p(n,"name",{value:e,configurable:!0});const g=["#000000","#800000","#008000","#808000","#000080","#800080","#008080","#c0c0c0","#808080","#ff0000","#00ff00","#ffff00","#0000ff","#ff00ff","#00ffff","#ffffff"];function a(n){if(n<16)return g[n];if(n<232){const i=n-16,t=Math.floor(i/36),l=Math.floor(i%36/6),c=i%6,s=o(u=>u===0?0:55+u*40,"toComponent"),r=o(u=>s(u).toString(16).padStart(2,"0"),"toHex");return`#${r(t)}${r(l)}${r(c)}`}const f=(8+(n-232)*10).toString(16).padStart(2,"0");return`#${f}${f}${f}`}o(a,"color256ToHex");function b(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}o(b,"escapeHtml");function $(){return{fg:null,bg:null,bold:!1,dim:!1,italic:!1,underline:!1}}o($,"createEmptyStyle");function S(n){const e=[];return n.fg&&e.push(`color:${n.fg}`),n.bg&&e.push(`background-color:${n.bg}`),n.bold&&e.push("font-weight:bold"),n.dim&&e.push("opacity:0.6"),n.italic&&e.push("font-style:italic"),n.underline&&e.push("text-decoration:underline"),e.join(";")}o(S,"styleToInlineCSS");function x(n){return n.fg!==null||n.bg!==null||n.bold||n.dim||n.italic||n.underline}o(x,"hasStyle");function I(n,e){let f=0;for(;f<n.length;){const i=n[f];if(i===0)e.fg=null,e.bg=null,e.bold=!1,e.dim=!1,e.italic=!1,e.underline=!1;else if(i===1)e.bold=!0;else if(i===2)e.dim=!0;else if(i===3)e.italic=!0;else if(i===4)e.underline=!0;else if(i===22)e.bold=!1,e.dim=!1;else if(i===23)e.italic=!1;else if(i===24)e.underline=!1;else if(i>=30&&i<=37)e.fg=g[i-30];else if(i===38){if(n[f+1]===5&&n.length>f+2)e.fg=a(n[f+2]),f+=2;else if(n[f+1]===2&&n.length>f+4){const t=n[f+2],l=n[f+3],c=n[f+4];e.fg=`rgb(${t},${l},${c})`,f+=4}}else if(i===39)e.fg=null;else if(i>=40&&i<=47)e.bg=g[i-40];else if(i===48){if(n[f+1]===5&&n.length>f+2)e.bg=a(n[f+2]),f+=2;else if(n[f+1]===2&&n.length>f+4){const t=n[f+2],l=n[f+3],c=n[f+4];e.bg=`rgb(${t},${l},${c})`,f+=4}}else i===49?e.bg=null:i>=90&&i<=97?e.fg=g[i-90+8]:i>=100&&i<=107&&(e.bg=g[i-100+8]);f++}}o(I,"applySgrCode");const d=/\x1b\[([\d;]*)m/g;function H(n){const e=$();let f="",i=0,t=!1;d.lastIndex=0;let l=d.exec(n);for(;l!==null;){const s=n.slice(i,l.index);s&&(f+=b(s));const r=l[1],u=r?r.split(";").map(h=>parseInt(h,10)||0):[0];t&&(f+="</span>",t=!1),I(u,e),x(e)&&(f+=`<span style="${S(e)}">`,t=!0),i=l.index+l[0].length,l=d.exec(n)}const c=n.slice(i);return c&&(f+=b(c)),t&&(f+="</span>"),f}o(H,"ansiToHtml");function C(n){return n.map(e=>`<div class="ansi-line">${H(e)||" "}</div>`).join("")}o(C,"ansiLinesToHtml");export{C as ansiLinesToHtml,H as ansiToHtml};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { AgentState } from "@openadapter/koda-agent-core";
|
|
2
|
+
import { SessionManager } from "../session-manager.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Interface for rendering custom tools to HTML.
|
|
5
|
+
* Used by agent-session to pre-render extension tool output.
|
|
6
|
+
*/
|
|
7
|
+
export interface ToolHtmlRenderer {
|
|
8
|
+
/** Render a tool call to HTML. Returns undefined if tool has no custom renderer. */
|
|
9
|
+
renderCall(toolCallId: string, toolName: string, args: unknown): string | undefined;
|
|
10
|
+
/** Render a tool result to HTML. Returns collapsed/expanded or undefined if tool has no custom renderer. */
|
|
11
|
+
renderResult(toolCallId: string, toolName: string, result: Array<{
|
|
12
|
+
type: string;
|
|
13
|
+
text?: string;
|
|
14
|
+
data?: string;
|
|
15
|
+
mimeType?: string;
|
|
16
|
+
}>, details: unknown, isError: boolean): {
|
|
17
|
+
collapsed?: string;
|
|
18
|
+
expanded?: string;
|
|
19
|
+
} | undefined;
|
|
20
|
+
}
|
|
21
|
+
export interface ExportOptions {
|
|
22
|
+
outputPath?: string;
|
|
23
|
+
themeName?: string;
|
|
24
|
+
/** Optional tool renderer for custom tools */
|
|
25
|
+
toolRenderer?: ToolHtmlRenderer;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Export session to HTML using SessionManager and AgentState.
|
|
29
|
+
* Used by TUI's /export command.
|
|
30
|
+
*/
|
|
31
|
+
export declare function exportSessionToHtml(sm: SessionManager, state?: AgentState, options?: ExportOptions | string): Promise<string>;
|
|
32
|
+
/**
|
|
33
|
+
* Export session file to HTML (standalone, without AgentState).
|
|
34
|
+
* Used by CLI for exporting arbitrary session files.
|
|
35
|
+
*/
|
|
36
|
+
export declare function exportFromFile(inputPath: string, options?: ExportOptions | string): Promise<string>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var H=Object.defineProperty;var c=(n,e)=>H(n,"name",{value:e,configurable:!0});import{existsSync as h,readFileSync as u,writeFileSync as B}from"fs";import{basename as E,join as m}from"path";import{APP_NAME as b,getExportTemplateDir as F}from"../../config.js";import{getResolvedThemeColors as x,getThemeExportColors as y}from"../../modes/interactive/theme/theme.js";import{normalizePath as I,resolvePath as v}from"../../utils/paths.js";import{SessionManager as D}from"../session-manager.js";function $(n){const e=n.match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);if(e)return{r:Number.parseInt(e[1],16),g:Number.parseInt(e[2],16),b:Number.parseInt(e[3],16)};const t=n.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/);if(t)return{r:Number.parseInt(t[1],10),g:Number.parseInt(t[2],10),b:Number.parseInt(t[3],10)}}c($,"parseColor");function L(n,e,t){const r=c(o=>{const s=o/255;return s<=.03928?s/12.92:((s+.055)/1.055)**2.4},"toLinear");return .2126*r(n)+.7152*r(e)+.0722*r(t)}c(L,"getLuminance");function d(n,e){const t=$(n);if(!t)return n;const r=c(o=>Math.min(255,Math.max(0,Math.round(o*e))),"adjust");return`rgb(${r(t.r)}, ${r(t.g)}, ${r(t.b)})`}c(d,"adjustBrightness");function M(n){const e=$(n);return e?L(e.r,e.g,e.b)>.5?{pageBg:d(n,.96),cardBg:n,infoBg:`rgb(${Math.min(255,e.r+10)}, ${Math.min(255,e.g+5)}, ${Math.max(0,e.b-20)})`}:{pageBg:d(n,.7),cardBg:d(n,.85),infoBg:`rgb(${Math.min(255,e.r+20)}, ${Math.min(255,e.g+15)}, ${e.b})`}:{pageBg:"rgb(24, 24, 30)",cardBg:"rgb(30, 30, 36)",infoBg:"rgb(60, 55, 40)"}}c(M,"deriveExportColors");function R(n){const e=x(n),t=[];for(const[a,i]of Object.entries(e))t.push(`--${a}: ${i};`);const r=y(n),o=e.userMessageBg||"#343541",s=M(o);return t.push(`--exportPageBg: ${r.pageBg??s.pageBg};`),t.push(`--exportCardBg: ${r.cardBg??s.cardBg};`),t.push(`--exportInfoBg: ${r.infoBg??s.infoBg};`),t.join(`
|
|
2
|
+
`)}c(R,"generateThemeVars");function S(n,e){const t=F(),r=u(m(t,"template.html"),"utf-8"),o=u(m(t,"template.css"),"utf-8"),s=u(m(t,"template.js"),"utf-8"),a=u(m(t,"vendor","marked.min.js"),"utf-8"),i=u(m(t,"vendor","highlight.min.js"),"utf-8"),p=R(e),g=x(e),l=y(e),f=M(g.userMessageBg||"#343541"),T=l.pageBg??f.pageBg,C=l.cardBg??f.cardBg,N=l.infoBg??f.infoBg,A=Buffer.from(JSON.stringify(n)).toString("base64"),j=o.replace("{{THEME_VARS}}",p).replace("{{BODY_BG}}",T).replace("{{CONTAINER_BG}}",C).replace("{{INFO_BG}}",N);return r.replace("{{CSS}}",j).replace("{{JS}}",s).replace("{{SESSION_DATA}}",A).replace("{{MARKED_JS}}",a).replace("{{HIGHLIGHT_JS}}",i)}c(S,"generateHtml");const P=new Set(["bash","read","write","edit","ls"]);function _(n,e){const t={};for(const r of n){if(r.type!=="message")continue;const o=r.message;if(o.role==="assistant"&&Array.isArray(o.content)){for(const s of o.content)if(s.type==="toolCall"&&!P.has(s.name)){const a=e.renderCall(s.id,s.name,s.arguments);a&&(t[s.id]={callHtml:a})}}if(o.role==="toolResult"&&o.toolCallId){const s=o.toolName||"",a=t[o.toolCallId];if(a||!P.has(s)){const i=e.renderResult(o.toolCallId,s,o.content,o.details,o.isError||!1);i&&(t[o.toolCallId]={...a,resultHtmlCollapsed:i.collapsed,resultHtmlExpanded:i.expanded})}}}return t}c(_,"preRenderCustomTools");async function K(n,e,t){const r=typeof t=="string"?{outputPath:t}:t||{},o=n.getSessionFile();if(!o)throw new Error("Cannot export in-memory session to HTML");if(!h(o))throw new Error("Nothing to export yet - start a conversation first");const s=n.getEntries();let a;r.toolRenderer&&(a=_(s,r.toolRenderer),Object.keys(a).length===0&&(a=void 0));const i={header:n.getHeader(),entries:s,leafId:n.getLeafId(),systemPrompt:e?.systemPrompt,tools:e?.tools?.map(l=>({name:l.name,description:l.description,parameters:l.parameters})),renderedTools:a},p=S(i,r.themeName);let g=r.outputPath?I(r.outputPath):void 0;if(!g){const l=E(o,".jsonl");g=`${b}-session-${l}.html`}return B(g,p,"utf8"),g}c(K,"exportSessionToHtml");async function Y(n,e){const t=typeof e=="string"?{outputPath:e}:e||{},r=v(n);if(!h(r))throw new Error(`File not found: ${r}`);const o=D.open(r),s={header:o.getHeader(),entries:o.getEntries(),leafId:o.getLeafId(),systemPrompt:void 0,tools:void 0},a=S(s,t.themeName);let i=t.outputPath?I(t.outputPath):void 0;if(!i){const p=E(r,".jsonl");i=`${b}-session-${p}.html`}return B(i,a,"utf8"),i}c(Y,"exportFromFile");export{Y as exportFromFile,K as exportSessionToHtml};
|