open-multi-agent-kit 0.91.0 → 0.93.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/CHANGELOG.md +32 -1
- package/README.md +2 -2
- package/dist/core/agent-session.d.ts +29 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +89 -21
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/command-safety.d.ts.map +1 -1
- package/dist/core/command-safety.js +0 -50
- package/dist/core/command-safety.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +5 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +5 -7
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +12 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +28 -15
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/transaction.d.ts.map +1 -1
- package/dist/core/compaction/transaction.js +7 -3
- package/dist/core/compaction/transaction.js.map +1 -1
- package/dist/core/context-budget-headroom-candidates.d.ts.map +1 -1
- package/dist/core/context-budget-headroom-candidates.js +21 -11
- package/dist/core/context-budget-headroom-candidates.js.map +1 -1
- package/dist/core/context-budget-system-prompt-items.d.ts +1 -0
- package/dist/core/context-budget-system-prompt-items.d.ts.map +1 -1
- package/dist/core/context-budget-system-prompt-items.js +7 -8
- package/dist/core/context-budget-system-prompt-items.js.map +1 -1
- package/dist/core/extensions/builtin/command-safety-gate.d.ts +8 -0
- package/dist/core/extensions/builtin/command-safety-gate.d.ts.map +1 -1
- package/dist/core/extensions/builtin/command-safety-gate.js +23 -0
- package/dist/core/extensions/builtin/command-safety-gate.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +4 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +2 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts +5 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +5 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/loadouts.d.ts.map +1 -1
- package/dist/core/loadouts.js +27 -48
- package/dist/core/loadouts.js.map +1 -1
- package/dist/core/model-resolver.d.ts +41 -3
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +17 -9
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/provider-resilience.d.ts.map +1 -1
- package/dist/core/provider-resilience.js +3 -1
- package/dist/core/provider-resilience.js.map +1 -1
- package/dist/core/reasoning-router-v4-weights.d.ts.map +1 -1
- package/dist/core/reasoning-router-v4-weights.js +9 -3
- package/dist/core/reasoning-router-v4-weights.js.map +1 -1
- package/dist/core/reasoning-router-v4.d.ts.map +1 -1
- package/dist/core/reasoning-router-v4.js +94 -24
- package/dist/core/reasoning-router-v4.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +11 -5
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/session-file-compaction.d.ts.map +1 -1
- package/dist/core/session-file-compaction.js +39 -5
- package/dist/core/session-file-compaction.js.map +1 -1
- package/dist/core/session-termination.d.ts.map +1 -1
- package/dist/core/session-termination.js +1 -1
- package/dist/core/session-termination.js.map +1 -1
- package/dist/core/settings-manager.d.ts +3 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +8 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +36 -31
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +38 -11
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +112 -11
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/control-panel-box.d.ts +27 -0
- package/dist/modes/interactive/components/control-panel-box.d.ts.map +1 -1
- package/dist/modes/interactive/components/control-panel-box.js +60 -8
- package/dist/modes/interactive/components/control-panel-box.js.map +1 -1
- package/dist/modes/interactive/components/control-panel-layout.d.ts.map +1 -1
- package/dist/modes/interactive/components/control-panel-layout.js +100 -45
- package/dist/modes/interactive/components/control-panel-layout.js.map +1 -1
- package/dist/modes/interactive/components/control-panel-runtime-status.d.ts +9 -0
- package/dist/modes/interactive/components/control-panel-runtime-status.d.ts.map +1 -1
- package/dist/modes/interactive/components/control-panel-runtime-status.js +10 -8
- package/dist/modes/interactive/components/control-panel-runtime-status.js.map +1 -1
- package/dist/modes/interactive/components/control-panel-sparkles.d.ts +5 -0
- package/dist/modes/interactive/components/control-panel-sparkles.d.ts.map +1 -1
- package/dist/modes/interactive/components/control-panel-sparkles.js +14 -9
- package/dist/modes/interactive/components/control-panel-sparkles.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +10 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +3 -3
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/status-sidebar.d.ts +49 -0
- package/dist/modes/interactive/components/status-sidebar.d.ts.map +1 -0
- package/dist/modes/interactive/components/status-sidebar.js +253 -0
- package/dist/modes/interactive/components/status-sidebar.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +9 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +94 -20
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/omk-neon-control.json +13 -13
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +9 -0
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +1 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +19 -8
- package/dist/utils/clipboard.js.map +1 -1
- package/docs/adaptorch-preview-spec.md +174 -0
- package/docs/adaptorch-preview.md +1 -1
- package/docs/compaction.md +20 -13
- package/docs/correctness-wall.md +13 -5
- package/docs/custom-provider.md +8 -8
- package/docs/development.md +2 -2
- package/docs/docs.json +4 -0
- package/docs/environment-variables.md +90 -0
- package/docs/extensions.md +8 -8
- package/docs/index.md +1 -0
- package/docs/json.md +4 -4
- package/docs/providers.md +1 -1
- package/docs/rpc.md +5 -2
- package/docs/session-format.md +5 -5
- package/docs/settings.md +1 -0
- package/docs/skills.md +2 -0
- package/docs/themes.md +2 -2
- package/docs/tui.md +4 -4
- package/docs/usage.md +4 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/README.md +35 -10
- package/examples/extensions/subagent/adaptive-agent-runtime.test.ts +234 -0
- package/examples/extensions/subagent/adaptive-agent-runtime.ts +240 -0
- package/examples/extensions/subagent/adaptive-result.ts +112 -0
- package/examples/extensions/subagent/agents.test.ts +86 -0
- package/examples/extensions/subagent/agents.ts +18 -4
- package/examples/extensions/subagent/capabilities.ts +15 -1
- package/examples/extensions/subagent/checkpoint-runtime.test.ts +125 -0
- package/examples/extensions/subagent/checkpoint-runtime.ts +198 -0
- package/examples/extensions/subagent/deadline-budget.test.ts +135 -0
- package/examples/extensions/subagent/deadline-budget.ts +242 -0
- package/examples/extensions/subagent/deadline-profile-store.test.ts +72 -0
- package/examples/extensions/subagent/deadline-profile-store.ts +172 -0
- package/examples/extensions/subagent/domain-profiles.ts +272 -0
- package/examples/extensions/subagent/fixtures/fake-omk-json.mjs +13 -0
- package/examples/extensions/subagent/fixtures/hanging-process-tree.mjs +40 -0
- package/examples/extensions/subagent/index.ts +253 -137
- package/examples/extensions/subagent/managed-process.test.ts +178 -0
- package/examples/extensions/subagent/managed-process.ts +236 -0
- package/examples/extensions/subagent/subagent-extension-smoke.test.ts +112 -0
- package/examples/extensions/subagent/subagent-runtime-types.ts +76 -0
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +21 -21
- package/package.json +10 -7
package/docs/json.md
CHANGED
|
@@ -8,7 +8,7 @@ Outputs all session events as JSON lines to stdout. Useful for integrating omk i
|
|
|
8
8
|
|
|
9
9
|
## Event Types
|
|
10
10
|
|
|
11
|
-
Events are defined in [`AgentSessionEvent`](https://github.com/
|
|
11
|
+
Events are defined in [`AgentSessionEvent`](https://github.com/dmae97/omk/blob/main/packages/coding-agent/src/core/agent-session.ts#L102):
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
14
|
type AgentSessionEvent =
|
|
@@ -22,7 +22,7 @@ type AgentSessionEvent =
|
|
|
22
22
|
|
|
23
23
|
`queue_update` emits the full pending steering and follow-up queues whenever they change. `compaction_start` and `compaction_end` cover both manual and automatic compaction.
|
|
24
24
|
|
|
25
|
-
Base events from [`AgentEvent`](https://github.com/
|
|
25
|
+
Base events from [`AgentEvent`](https://github.com/dmae97/omk/blob/main/packages/agent/src/types.ts#L179):
|
|
26
26
|
|
|
27
27
|
```typescript
|
|
28
28
|
type AgentEvent =
|
|
@@ -44,12 +44,12 @@ type AgentEvent =
|
|
|
44
44
|
|
|
45
45
|
## Message Types
|
|
46
46
|
|
|
47
|
-
Base messages from [`packages/ai/src/types.ts`](https://github.com/
|
|
47
|
+
Base messages from [`packages/ai/src/types.ts`](https://github.com/dmae97/omk/blob/main/packages/ai/src/types.ts#L134):
|
|
48
48
|
- `UserMessage` (line 134)
|
|
49
49
|
- `AssistantMessage` (line 140)
|
|
50
50
|
- `ToolResultMessage` (line 152)
|
|
51
51
|
|
|
52
|
-
Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://github.com/
|
|
52
|
+
Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://github.com/dmae97/omk/blob/main/packages/coding-agent/src/core/messages.ts#L29):
|
|
53
53
|
- `BashExecutionMessage` (line 29)
|
|
54
54
|
- `CustomMessage` (line 46)
|
|
55
55
|
- `BranchSummaryMessage` (line 55)
|
package/docs/providers.md
CHANGED
|
@@ -89,7 +89,7 @@ omk
|
|
|
89
89
|
| Xiaomi MiMo Token Plan (Singapore) | `XIAOMI_TOKEN_PLAN_SGP_API_KEY` | `xiaomi-token-plan-sgp` |
|
|
90
90
|
| Zyloo | `ZYLOO_API_KEY` | `zyloo` |
|
|
91
91
|
|
|
92
|
-
Reference for environment variables and `auth.json` keys: [`const envMap`](https://github.com/
|
|
92
|
+
Reference for environment variables and `auth.json` keys: [`const envMap`](https://github.com/dmae97/omk/blob/main/packages/ai/src/env-api-keys.ts) in [`packages/ai/src/env-api-keys.ts`](https://github.com/dmae97/omk/blob/main/packages/ai/src/env-api-keys.ts).
|
|
93
93
|
|
|
94
94
|
#### Zyloo
|
|
95
95
|
|
package/docs/rpc.md
CHANGED
|
@@ -424,12 +424,14 @@ Response:
|
|
|
424
424
|
|
|
425
425
|
#### bash
|
|
426
426
|
|
|
427
|
-
Execute a shell command and add output to conversation context.
|
|
427
|
+
Execute a shell command and add output to conversation context. Output streams as `bash_execution_update` events while the command runs; the response contains the final result.
|
|
428
428
|
|
|
429
429
|
```json
|
|
430
|
-
{"type": "bash", "command": "ls -la"}
|
|
430
|
+
{"id": "req-1", "type": "bash", "command": "ls -la"}
|
|
431
431
|
```
|
|
432
432
|
|
|
433
|
+
Include an `id` to associate streamed `bash_execution_update` events with this command.
|
|
434
|
+
|
|
433
435
|
Response:
|
|
434
436
|
```json
|
|
435
437
|
{
|
|
@@ -753,6 +755,7 @@ Events are streamed to stdout as JSON lines during agent operation. Events do NO
|
|
|
753
755
|
| `message_start` | Message begins |
|
|
754
756
|
| `message_update` | Streaming update (text/thinking/toolcall deltas) |
|
|
755
757
|
| `message_end` | Message completes |
|
|
758
|
+
| `bash_execution_update` | Direct RPC bash command output chunk (includes originating command `id`) |
|
|
756
759
|
| `tool_execution_start` | Tool begins execution |
|
|
757
760
|
| `tool_execution_update` | Tool execution progress (streaming output) |
|
|
758
761
|
| `tool_execution_end` | Tool completes |
|
package/docs/session-format.md
CHANGED
|
@@ -28,11 +28,11 @@ Existing sessions are automatically migrated to the current version (v3) when lo
|
|
|
28
28
|
|
|
29
29
|
## Source Files
|
|
30
30
|
|
|
31
|
-
Source on GitHub ([omk-mono](https://github.com/
|
|
32
|
-
- [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/
|
|
33
|
-
- [`packages/coding-agent/src/core/messages.ts`](https://github.com/
|
|
34
|
-
- [`packages/ai/src/types.ts`](https://github.com/
|
|
35
|
-
- [`packages/agent/src/types.ts`](https://github.com/
|
|
31
|
+
Source on GitHub ([omk-mono](https://github.com/dmae97/omk)):
|
|
32
|
+
- [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/dmae97/omk/blob/main/packages/coding-agent/src/core/session-manager.ts) - Session entry types and SessionManager
|
|
33
|
+
- [`packages/coding-agent/src/core/messages.ts`](https://github.com/dmae97/omk/blob/main/packages/coding-agent/src/core/messages.ts) - Extended message types (BashExecutionMessage, CustomMessage, etc.)
|
|
34
|
+
- [`packages/ai/src/types.ts`](https://github.com/dmae97/omk/blob/main/packages/ai/src/types.ts) - Base message types (UserMessage, AssistantMessage, ToolResultMessage)
|
|
35
|
+
- [`packages/agent/src/types.ts`](https://github.com/dmae97/omk/blob/main/packages/agent/src/types.ts) - AgentMessage union type
|
|
36
36
|
|
|
37
37
|
For TypeScript definitions in your project, inspect `node_modules/open-multi-agent-kit/dist/` and `node_modules/omk-ai/dist/`.
|
|
38
38
|
|
package/docs/settings.md
CHANGED
|
@@ -77,6 +77,7 @@ Advisory-only hint source for the v4 auto thinking-level resolver. Read from the
|
|
|
77
77
|
| `editorPaddingX` | number | `0` | Horizontal padding for input editor (0-3) |
|
|
78
78
|
| `autocompleteMaxVisible` | number | `5` | Max visible items in autocomplete dropdown (3-20) |
|
|
79
79
|
| `showHardwareCursor` | boolean | `false` | Show the terminal cursor while TUI positions it for IME support |
|
|
80
|
+
| `pinStatusSidebar` | boolean | `false` | Pin the bottom status bar as a responsive right rail (opencode-style): width scales with the terminal (~26%, 34–48 cols), the MCP roster grows on taller terminals, and the content column shrinks to match so the prompt is never covered. Toggle anytime with `Ctrl+Q`. Also enabled by `OMK_PIN_STATUS_SIDEBAR=1` |
|
|
80
81
|
|
|
81
82
|
### Telemetry and update checks
|
|
82
83
|
|
package/docs/skills.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
Skills are self-contained capability packages that the agent loads on-demand. A skill provides specialized workflows, setup instructions, helper scripts, and reference documentation for specific tasks.
|
|
6
6
|
|
|
7
|
+
OMK ships with **no built-in skills** — every skill is user-installed via the locations below, an OMK package, or `--skill`. The default session has zero skills and zero MCP servers configured.
|
|
8
|
+
|
|
7
9
|
OMK implements the [Agent Skills standard](https://agentskills.io/specification), warning about most violations but remaining lenient. OMK allows skill names to differ from their parent directory even though the standard disallows it; that rule is suboptimal for shared skill directories used across multiple agent harnesses.
|
|
8
10
|
|
|
9
11
|
## Table of Contents
|
package/docs/themes.md
CHANGED
|
@@ -56,7 +56,7 @@ vim ~/.omk/agent/themes/my-theme.json
|
|
|
56
56
|
|
|
57
57
|
```json
|
|
58
58
|
{
|
|
59
|
-
"$schema": "https://raw.githubusercontent.com/
|
|
59
|
+
"$schema": "https://raw.githubusercontent.com/dmae97/omk/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
60
60
|
"name": "my-theme",
|
|
61
61
|
"vars": {
|
|
62
62
|
"primary": "#00aaff",
|
|
@@ -126,7 +126,7 @@ vim ~/.omk/agent/themes/my-theme.json
|
|
|
126
126
|
|
|
127
127
|
```json
|
|
128
128
|
{
|
|
129
|
-
"$schema": "https://raw.githubusercontent.com/
|
|
129
|
+
"$schema": "https://raw.githubusercontent.com/dmae97/omk/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
130
130
|
"name": "my-theme",
|
|
131
131
|
"vars": {
|
|
132
132
|
"blue": "#0066cc",
|
package/docs/tui.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Extensions and custom tools can render custom TUI components for interactive user interfaces. This page covers the component system and available building blocks.
|
|
6
6
|
|
|
7
|
-
**Source:** [`omk-tui`](https://github.com/
|
|
7
|
+
**Source:** [`omk-tui`](https://github.com/dmae97/omk/tree/main/packages/tui)
|
|
8
8
|
|
|
9
9
|
## Component Interface
|
|
10
10
|
|
|
@@ -742,7 +742,7 @@ ctx.ui.setStatus("my-ext", ctx.ui.theme.fg("accent", "● active"));
|
|
|
742
742
|
ctx.ui.setStatus("my-ext", undefined);
|
|
743
743
|
```
|
|
744
744
|
|
|
745
|
-
**Examples:** [status-line.ts](../examples/extensions/status-line.ts), [plan-mode.ts](../examples/extensions/plan-mode.ts), [preset.ts](../examples/extensions/preset.ts)
|
|
745
|
+
**Examples:** [status-line.ts](../examples/extensions/status-line.ts), [plan-mode.ts](../examples/extensions/plan-mode/index.ts), [preset.ts](../examples/extensions/preset.ts)
|
|
746
746
|
|
|
747
747
|
### Pattern 4b: Working Indicator Customization
|
|
748
748
|
|
|
@@ -802,7 +802,7 @@ ctx.ui.setWidget("my-widget", (_tui, theme) => {
|
|
|
802
802
|
ctx.ui.setWidget("my-widget", undefined);
|
|
803
803
|
```
|
|
804
804
|
|
|
805
|
-
**Examples:** [plan-mode.ts](../examples/extensions/plan-mode.ts)
|
|
805
|
+
**Examples:** [plan-mode.ts](../examples/extensions/plan-mode/index.ts)
|
|
806
806
|
|
|
807
807
|
### Pattern 6: Custom Footer
|
|
808
808
|
|
|
@@ -919,7 +919,7 @@ export default function (omk: ExtensionAPI) {
|
|
|
919
919
|
- **Selection UI**: [examples/extensions/preset.ts](../examples/extensions/preset.ts) - SelectList with DynamicBorder framing
|
|
920
920
|
- **Async with cancel**: [examples/extensions/qna.ts](../examples/extensions/qna.ts) - BorderedLoader for LLM calls
|
|
921
921
|
- **Settings toggles**: [examples/extensions/tools.ts](../examples/extensions/tools.ts) - SettingsList for tool enable/disable
|
|
922
|
-
- **Status indicators**: [examples/extensions/plan-mode.ts](../examples/extensions/plan-mode.ts) - setStatus and setWidget
|
|
922
|
+
- **Status indicators**: [examples/extensions/plan-mode/index.ts](../examples/extensions/plan-mode/index.ts) - setStatus and setWidget
|
|
923
923
|
- **Working indicator**: [examples/extensions/working-indicator.ts](../examples/extensions/working-indicator.ts) - setWorkingIndicator
|
|
924
924
|
- **Custom footer**: [examples/extensions/custom-footer.ts](../examples/extensions/custom-footer.ts) - setFooter with stats
|
|
925
925
|
- **Custom editor**: [examples/extensions/modal-editor.ts](../examples/extensions/modal-editor.ts) - Vim-like modal editing
|
package/docs/usage.md
CHANGED
|
@@ -151,6 +151,8 @@ OMK loads `AGENTS.md` or `CLAUDE.md` at startup from:
|
|
|
151
151
|
|
|
152
152
|
Use context files for project conventions, commands, safety rules, and preferences. Disable loading with `--no-context-files` or `-nc`.
|
|
153
153
|
|
|
154
|
+
The core prompt builder places a fixed runtime trust boundary before loaded context and skill metadata. Global context can constrain project context, but loaded resources cannot expand user authorization or override active runtime/security controls. Context paths and text are XML-escaped before prompt assembly so resource content cannot break out of its structural envelope. This is defense in depth, not a code sandbox: extensions are executable trusted code and can explicitly rewrite the system prompt or final provider payload.
|
|
155
|
+
|
|
154
156
|
### System Prompt Files
|
|
155
157
|
|
|
156
158
|
Replace the default system prompt with:
|
|
@@ -160,6 +162,8 @@ Replace the default system prompt with:
|
|
|
160
162
|
|
|
161
163
|
Append to the default prompt without replacing it with `APPEND_SYSTEM.md` in either location.
|
|
162
164
|
|
|
165
|
+
Replacing or appending the default prompt does not remove the core runtime trust boundary; OMK inserts it after custom prompt text and before context files and skills.
|
|
166
|
+
|
|
163
167
|
## Exporting and Sharing Sessions
|
|
164
168
|
|
|
165
169
|
Use `/export [file]` to write a session to HTML.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omk-extension-custom-provider-anthropic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.93.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omk-extension-custom-provider-anthropic",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.93.0",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "0.52.0"
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omk-extension-gondolin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.93.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omk-extension-gondolin",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.93.0",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@earendil-works/gondolin": "0.12.0"
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omk-extension-sandbox",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.93.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omk-extension-sandbox",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.93.0",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sandbox-runtime": "0.0.26"
|
|
12
12
|
}
|
|
@@ -9,15 +9,25 @@ Delegate tasks to specialized subagents with isolated context windows.
|
|
|
9
9
|
- **Parallel streaming**: All parallel tasks stream updates simultaneously
|
|
10
10
|
- **Markdown rendering**: Final output rendered with proper formatting (expanded view)
|
|
11
11
|
- **Usage tracking**: Shows turns, tokens, cost, and context usage per agent
|
|
12
|
-
- **Abort support**: Ctrl+C propagates to
|
|
12
|
+
- **Abort support**: Ctrl+C propagates to the entire detached subagent process tree
|
|
13
|
+
- **Dual-budget planning**: Predictive sharding uses both estimated tokens and learned wall-clock demand
|
|
14
|
+
- **Checkpoint resume**: A cutoff resumes only the unfinished shard with bounded prior evidence
|
|
15
|
+
- **Cutoff learning**: Completion/cutoff history is persisted per provider and model under the agent state directory
|
|
16
|
+
- **Bounded cost**: At most 3 semantic shards and 1 resume across the whole logical task by default
|
|
13
17
|
|
|
14
18
|
## Structure
|
|
15
19
|
|
|
16
20
|
```
|
|
17
21
|
subagent/
|
|
18
22
|
├── README.md # This file
|
|
19
|
-
├── index.ts
|
|
20
|
-
├──
|
|
23
|
+
├── index.ts # The extension entry point
|
|
24
|
+
├── adaptive-agent-runtime.ts # Shard/checkpoint/resume coordinator
|
|
25
|
+
├── checkpoint-runtime.ts # Bounded checkpoint protocol
|
|
26
|
+
├── deadline-budget.ts # Token + wall-clock planning and cutoff learning
|
|
27
|
+
├── deadline-profile-store.ts # Persistent provider/model profiles
|
|
28
|
+
├── managed-process.ts # Process-tree termination and cleanup
|
|
29
|
+
├── subagent-runtime-types.ts # Typed result/deadline metadata
|
|
30
|
+
├── agents.ts # Agent discovery logic
|
|
21
31
|
├── agents/ # Sample agent definitions
|
|
22
32
|
│ ├── scout.md # Fast recon, returns compressed context
|
|
23
33
|
│ ├── planner.md # Creates implementation plans
|
|
@@ -36,8 +46,12 @@ From the repository root, symlink the files:
|
|
|
36
46
|
```bash
|
|
37
47
|
# Symlink the extension (must be in a subdirectory with index.ts)
|
|
38
48
|
mkdir -p ~/.omk/agent/extensions/subagent
|
|
39
|
-
|
|
40
|
-
|
|
49
|
+
src="$(pwd)/packages/coding-agent/examples/extensions/subagent"
|
|
50
|
+
for f in index.ts agents.ts agent-capability-router.ts capabilities.ts domain-profiles.ts \
|
|
51
|
+
adaptive-agent-runtime.ts adaptive-result.ts checkpoint-runtime.ts deadline-budget.ts \
|
|
52
|
+
deadline-profile-store.ts managed-process.ts subagent-runtime-types.ts; do
|
|
53
|
+
ln -sf "$src/$f" ~/.omk/agent/extensions/subagent/$f
|
|
54
|
+
done
|
|
41
55
|
|
|
42
56
|
# Symlink agents
|
|
43
57
|
mkdir -p ~/.omk/agent/agents
|
|
@@ -92,9 +106,16 @@ Use a chain: first have scout find the read tool, then have planner suggest impr
|
|
|
92
106
|
|
|
93
107
|
| Mode | Parameter | Description |
|
|
94
108
|
|------|-----------|-------------|
|
|
95
|
-
| Single | `{ agent, task }` | One
|
|
96
|
-
| Parallel | `{ tasks: [...] }` | Multiple
|
|
97
|
-
| Chain | `{ chain: [...] }` | Sequential with `{previous}` placeholder |
|
|
109
|
+
| Single | `{ agent, task }` | One logical task; the runtime may split it into bounded semantic shards |
|
|
110
|
+
| Parallel | `{ tasks: [...] }` | Multiple logical tasks run concurrently (max 8, 4 concurrent) |
|
|
111
|
+
| Chain | `{ chain: [...] }` | Sequential with `{previous}` placeholder and a fair deadline share per remaining step |
|
|
112
|
+
|
|
113
|
+
Optional execution controls:
|
|
114
|
+
|
|
115
|
+
| Parameter | Default | Description |
|
|
116
|
+
|-----------|---------|-------------|
|
|
117
|
+
| `executionBudgetMs` | `840000` | Internal hard budget, leaving 60 seconds before a configured 900000 ms tool timeout |
|
|
118
|
+
| `maxResumeAttempts` | `1` | Retries only the active unfinished shard; accepted range is 0-2 |
|
|
98
119
|
|
|
99
120
|
## Output Display
|
|
100
121
|
|
|
@@ -164,8 +185,10 @@ Project agents override user agents with the same name when `agentScope: "both"`
|
|
|
164
185
|
|
|
165
186
|
- **Exit code != 0**: Tool returns error with stderr/output
|
|
166
187
|
- **stopReason "error"**: LLM error propagated with error message
|
|
167
|
-
- **stopReason "aborted"**: User abort (Ctrl+C)
|
|
168
|
-
- **
|
|
188
|
+
- **stopReason "aborted"**: User abort (Ctrl+C) terminates and reaps the subprocess tree
|
|
189
|
+
- **stopReason "deadline"**: Internal cutoff returns elapsed/deadline/checkpoint/resume metadata instead of reaching the outer tool timeout
|
|
190
|
+
- **Chain mode**: Stops at first failing step, reports which step failed, and preserves completed earlier steps
|
|
191
|
+
- **Duplicate prevention**: A cutoff with no new checkpoint or streamed evidence is not retried
|
|
169
192
|
|
|
170
193
|
## Limitations
|
|
171
194
|
|
|
@@ -173,3 +196,5 @@ Project agents override user agents with the same name when `agentScope: "both"`
|
|
|
173
196
|
- Parallel model-visible output is capped at 50 KB per task; full results remain in tool details
|
|
174
197
|
- Agents discovered fresh on each invocation (allows editing mid-session)
|
|
175
198
|
- Parallel mode limited to 8 tasks, 4 concurrent
|
|
199
|
+
- Automatic semantic pre-sharding requires an explicit numbered/checklist action list; indivisible prose is checkpointed and resumed as one shard
|
|
200
|
+
- Checkpoints are best-effort child artifacts plus runtime-captured stream evidence; workspace side effects remain the source of truth after a cutoff
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import type { Message } from "omk-ai";
|
|
5
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
6
|
+
import { type RunAttemptInput, runAdaptiveAgent } from "./adaptive-agent-runtime.ts";
|
|
7
|
+
import { createExecutionBudget } from "./deadline-budget.ts";
|
|
8
|
+
import { DeadlineProfileStore } from "./deadline-profile-store.ts";
|
|
9
|
+
import { emptyUsage, type SingleResult, type SubagentAttemptResult } from "./subagent-runtime-types.ts";
|
|
10
|
+
|
|
11
|
+
const cleanupPaths: string[] = [];
|
|
12
|
+
|
|
13
|
+
function assistant(text: string): Message {
|
|
14
|
+
return { role: "assistant", content: [{ type: "text", text }] } as Message;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function attempt(input: RunAttemptInput, outcome: "completed" | "cutoff" | "failed", text = ""): SubagentAttemptResult {
|
|
18
|
+
const exitCode = outcome === "completed" ? 0 : outcome === "failed" ? 1 : 124;
|
|
19
|
+
const result: SingleResult = {
|
|
20
|
+
agent: "reviewer",
|
|
21
|
+
agentSource: "user",
|
|
22
|
+
task: input.logicalTask,
|
|
23
|
+
exitCode,
|
|
24
|
+
messages: text === "" ? [] : [assistant(text)],
|
|
25
|
+
stderr: "",
|
|
26
|
+
usage: emptyUsage(),
|
|
27
|
+
output: text,
|
|
28
|
+
model: "openai-codex/gpt-5.6",
|
|
29
|
+
...(outcome === "cutoff"
|
|
30
|
+
? { stopReason: "deadline", errorMessage: "attempt cutoff" }
|
|
31
|
+
: { stopReason: outcome === "failed" ? "error" : "end" }),
|
|
32
|
+
};
|
|
33
|
+
return {
|
|
34
|
+
result,
|
|
35
|
+
process: {
|
|
36
|
+
reason: outcome === "failed" ? "completed" : outcome,
|
|
37
|
+
elapsedMs: outcome === "completed" ? 10 : input.cutoffMs,
|
|
38
|
+
cleanup: { termSent: outcome === "cutoff", killSent: false, processGroup: true },
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
afterEach(async () => {
|
|
44
|
+
await Promise.all(cleanupPaths.splice(0).map((entry) => fs.promises.rm(entry, { recursive: true, force: true })));
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe("adaptive subagent execution", () => {
|
|
48
|
+
it("resumes only the unfinished shard from bounded checkpoint evidence", async () => {
|
|
49
|
+
const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "omk-adaptive-resume-"));
|
|
50
|
+
cleanupPaths.push(dir);
|
|
51
|
+
const calls: RunAttemptInput[] = [];
|
|
52
|
+
const outputs = ["completed boundary inspection", "finished remaining cleanup"];
|
|
53
|
+
const result = await runAdaptiveAgent({
|
|
54
|
+
agentName: "reviewer",
|
|
55
|
+
agentSource: "user",
|
|
56
|
+
logicalTask: "Review and fix the process boundary.",
|
|
57
|
+
model: "openai-codex/gpt-5.6",
|
|
58
|
+
budget: createExecutionBudget({
|
|
59
|
+
hardDeadlineMs: 5_000,
|
|
60
|
+
cleanupReserveMs: 100,
|
|
61
|
+
maxResumeAttempts: 1,
|
|
62
|
+
maxTaskShards: 3,
|
|
63
|
+
}),
|
|
64
|
+
pendingSequentialTasks: 1,
|
|
65
|
+
checkpointPrefix: path.join(dir, "checkpoint-"),
|
|
66
|
+
profileStore: new DeadlineProfileStore(path.join(dir, "profiles.json")),
|
|
67
|
+
policy: { fallbackAttemptMs: 1_000, minimumAttemptMs: 1, maxTokensPerShard: 6_000 },
|
|
68
|
+
runAttempt: async (input) => {
|
|
69
|
+
calls.push(input);
|
|
70
|
+
return attempt(input, calls.length === 1 ? "cutoff" : "completed", outputs[calls.length - 1]);
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
expect(calls).toHaveLength(2);
|
|
75
|
+
expect(calls[1]?.task).toContain("completed boundary inspection");
|
|
76
|
+
expect(calls[1]?.task).toContain("Do not repeat completed side effects");
|
|
77
|
+
expect(result.deadline).toMatchObject({ outcome: "completed", resumeCount: 1, completedShardIds: ["shard-1"] });
|
|
78
|
+
expect(result.output).toContain("completed boundary inspection");
|
|
79
|
+
expect(result.output).toContain("finished remaining cleanup");
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("learns the provider/model observed from output when the agent inherits its model", async () => {
|
|
83
|
+
const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "omk-adaptive-observed-model-"));
|
|
84
|
+
cleanupPaths.push(dir);
|
|
85
|
+
const store = new DeadlineProfileStore(path.join(dir, "profiles.json"));
|
|
86
|
+
const result = await runAdaptiveAgent({
|
|
87
|
+
agentName: "reviewer",
|
|
88
|
+
agentSource: "user",
|
|
89
|
+
logicalTask: "Review the process boundary.",
|
|
90
|
+
budget: createExecutionBudget({
|
|
91
|
+
hardDeadlineMs: 5_000,
|
|
92
|
+
cleanupReserveMs: 100,
|
|
93
|
+
maxResumeAttempts: 1,
|
|
94
|
+
maxTaskShards: 3,
|
|
95
|
+
}),
|
|
96
|
+
pendingSequentialTasks: 1,
|
|
97
|
+
checkpointPrefix: path.join(dir, "checkpoint-"),
|
|
98
|
+
profileStore: store,
|
|
99
|
+
policy: { fallbackAttemptMs: 1_000, minimumAttemptMs: 1, maxTokensPerShard: 6_000 },
|
|
100
|
+
runAttempt: async (input) => attempt(input, "completed", "review complete"),
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
expect(result.deadline).toMatchObject({ provider: "openai-codex", model: "gpt-5.6" });
|
|
104
|
+
expect(await store.profileFor("openai-codex", "gpt-5.6")).toMatchObject({ samples: 1, completions: 1 });
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("preserves process failures instead of labeling them as deadline cutoffs", async () => {
|
|
108
|
+
const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "omk-adaptive-failure-"));
|
|
109
|
+
cleanupPaths.push(dir);
|
|
110
|
+
const result = await runAdaptiveAgent({
|
|
111
|
+
agentName: "reviewer",
|
|
112
|
+
agentSource: "user",
|
|
113
|
+
logicalTask: "Run the failing fixture.",
|
|
114
|
+
budget: createExecutionBudget({
|
|
115
|
+
hardDeadlineMs: 5_000,
|
|
116
|
+
cleanupReserveMs: 100,
|
|
117
|
+
maxResumeAttempts: 1,
|
|
118
|
+
maxTaskShards: 3,
|
|
119
|
+
}),
|
|
120
|
+
pendingSequentialTasks: 1,
|
|
121
|
+
checkpointPrefix: path.join(dir, "checkpoint-"),
|
|
122
|
+
profileStore: new DeadlineProfileStore(path.join(dir, "profiles.json")),
|
|
123
|
+
policy: { fallbackAttemptMs: 1_000, minimumAttemptMs: 1, maxTokensPerShard: 6_000 },
|
|
124
|
+
runAttempt: async (input) => attempt(input, "failed", ""),
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
expect(result).toMatchObject({ exitCode: 1, stopReason: "error", errorMessage: "Subagent process failed" });
|
|
128
|
+
expect(result.deadline).toMatchObject({ outcome: "failed" });
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it("does not retry a cutoff that produced no checkpoint or streamed progress", async () => {
|
|
132
|
+
const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "omk-adaptive-duplicate-"));
|
|
133
|
+
cleanupPaths.push(dir);
|
|
134
|
+
let calls = 0;
|
|
135
|
+
const result = await runAdaptiveAgent({
|
|
136
|
+
agentName: "reviewer",
|
|
137
|
+
agentSource: "user",
|
|
138
|
+
logicalTask: "Review the process boundary.",
|
|
139
|
+
model: "openai-codex/gpt-5.6",
|
|
140
|
+
budget: createExecutionBudget({
|
|
141
|
+
hardDeadlineMs: 5_000,
|
|
142
|
+
cleanupReserveMs: 100,
|
|
143
|
+
maxResumeAttempts: 2,
|
|
144
|
+
maxTaskShards: 3,
|
|
145
|
+
}),
|
|
146
|
+
pendingSequentialTasks: 1,
|
|
147
|
+
checkpointPrefix: path.join(dir, "checkpoint-"),
|
|
148
|
+
profileStore: new DeadlineProfileStore(path.join(dir, "profiles.json")),
|
|
149
|
+
policy: { fallbackAttemptMs: 1_000, minimumAttemptMs: 1, maxTokensPerShard: 6_000 },
|
|
150
|
+
runAttempt: async (input) => {
|
|
151
|
+
calls += 1;
|
|
152
|
+
return attempt(input, "cutoff");
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
expect(calls).toBe(1);
|
|
157
|
+
expect(result.deadline).toMatchObject({ outcome: "cutoff", resumeCount: 0, duplicateResumeBlocked: true });
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("never re-executes shards that already completed", async () => {
|
|
161
|
+
const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "omk-adaptive-shards-"));
|
|
162
|
+
cleanupPaths.push(dir);
|
|
163
|
+
const shardIds: string[] = [];
|
|
164
|
+
const task = [
|
|
165
|
+
"Upgrade runtime:",
|
|
166
|
+
"1. Inspect the process.",
|
|
167
|
+
"2. Add cleanup.",
|
|
168
|
+
"3. Implement metadata.",
|
|
169
|
+
"4. Run tests.",
|
|
170
|
+
].join("\n");
|
|
171
|
+
const result = await runAdaptiveAgent({
|
|
172
|
+
agentName: "worker",
|
|
173
|
+
agentSource: "user",
|
|
174
|
+
logicalTask: task,
|
|
175
|
+
model: "anthropic/claude-sonnet",
|
|
176
|
+
budget: createExecutionBudget({
|
|
177
|
+
hardDeadlineMs: 5_000,
|
|
178
|
+
cleanupReserveMs: 100,
|
|
179
|
+
maxResumeAttempts: 1,
|
|
180
|
+
maxTaskShards: 3,
|
|
181
|
+
}),
|
|
182
|
+
pendingSequentialTasks: 1,
|
|
183
|
+
checkpointPrefix: path.join(dir, "checkpoint-"),
|
|
184
|
+
profileStore: new DeadlineProfileStore(path.join(dir, "profiles.json")),
|
|
185
|
+
policy: { fallbackAttemptMs: 200, minimumAttemptMs: 1, maxTokensPerShard: 20 },
|
|
186
|
+
runAttempt: async (input) => {
|
|
187
|
+
shardIds.push(input.shardId);
|
|
188
|
+
return attempt(input, "completed", `done ${input.shardId}`);
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
expect(shardIds.length).toBeGreaterThan(1);
|
|
193
|
+
expect(new Set(shardIds).size).toBe(shardIds.length);
|
|
194
|
+
expect(result.deadline?.remainingShardIds).toEqual([]);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("caps resume cost across the whole logical task rather than once per shard", async () => {
|
|
198
|
+
const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "omk-adaptive-cost-cap-"));
|
|
199
|
+
cleanupPaths.push(dir);
|
|
200
|
+
const shardIds: string[] = [];
|
|
201
|
+
const task = [
|
|
202
|
+
"Upgrade runtime:",
|
|
203
|
+
"1. Inspect the process.",
|
|
204
|
+
"2. Add cleanup.",
|
|
205
|
+
"3. Implement metadata.",
|
|
206
|
+
"4. Run tests.",
|
|
207
|
+
].join("\n");
|
|
208
|
+
const result = await runAdaptiveAgent({
|
|
209
|
+
agentName: "worker",
|
|
210
|
+
agentSource: "user",
|
|
211
|
+
logicalTask: task,
|
|
212
|
+
model: "openai-codex/gpt-5.6",
|
|
213
|
+
budget: createExecutionBudget({
|
|
214
|
+
hardDeadlineMs: 5_000,
|
|
215
|
+
cleanupReserveMs: 100,
|
|
216
|
+
maxResumeAttempts: 1,
|
|
217
|
+
maxTaskShards: 3,
|
|
218
|
+
}),
|
|
219
|
+
pendingSequentialTasks: 1,
|
|
220
|
+
checkpointPrefix: path.join(dir, "checkpoint-"),
|
|
221
|
+
profileStore: new DeadlineProfileStore(path.join(dir, "profiles.json")),
|
|
222
|
+
policy: { fallbackAttemptMs: 200, minimumAttemptMs: 1, maxTokensPerShard: 20 },
|
|
223
|
+
runAttempt: async (input) => {
|
|
224
|
+
shardIds.push(input.shardId);
|
|
225
|
+
const outcome = shardIds.length === 2 ? "completed" : "cutoff";
|
|
226
|
+
return attempt(input, outcome, `progress ${input.shardId} ${shardIds.length}`);
|
|
227
|
+
},
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
expect(shardIds).toEqual(["shard-1", "shard-1", "shard-2"]);
|
|
231
|
+
expect(result.deadline).toMatchObject({ resumeCount: 1, outcome: "cutoff" });
|
|
232
|
+
expect(result.deadline?.remainingShardIds).toContain("shard-2");
|
|
233
|
+
});
|
|
234
|
+
});
|