indusagi-coding-agent 0.2.3 → 0.2.5
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 +25 -0
- package/LICENSE +661 -0
- package/README.md +95 -1
- package/dist/entry.js +3205 -1585
- package/dist/guardrails.js +47 -515
- package/dist/index.js +3232 -1671
- package/package.json +8 -7
- package/dist/types/addons/addons.test.d.ts +0 -21
- package/dist/types/addons/contract.d.ts +0 -640
- package/dist/types/addons/dispatch/event-dispatcher.d.ts +0 -140
- package/dist/types/addons/dispatch/index.d.ts +0 -23
- package/dist/types/addons/dispatch/tool-interceptor.d.ts +0 -128
- package/dist/types/addons/host.d.ts +0 -246
- package/dist/types/addons/index.d.ts +0 -51
- package/dist/types/addons/manifest.d.ts +0 -56
- package/dist/types/addons/sandbox.d.ts +0 -103
- package/dist/types/addons/surface.d.ts +0 -42
- package/dist/types/boot/auth-vault.d.ts +0 -29
- package/dist/types/boot/boot.d.ts +0 -26
- package/dist/types/boot/boot.test.d.ts +0 -15
- package/dist/types/boot/contract.d.ts +0 -236
- package/dist/types/boot/index.d.ts +0 -20
- package/dist/types/boot/invocation.d.ts +0 -40
- package/dist/types/boot/invocation.test.d.ts +0 -8
- package/dist/types/boot/runners/addon-wiring.d.ts +0 -103
- package/dist/types/boot/runners/addon-wiring.test.d.ts +0 -19
- package/dist/types/boot/runners/checkpoint.d.ts +0 -133
- package/dist/types/boot/runners/checkpoint.test.d.ts +0 -12
- package/dist/types/boot/runners/delegate-runner.d.ts +0 -89
- package/dist/types/boot/runners/delegate-runner.test.d.ts +0 -13
- package/dist/types/boot/runners/index.d.ts +0 -13
- package/dist/types/boot/runners/link-runner.d.ts +0 -20
- package/dist/types/boot/runners/memdir.d.ts +0 -103
- package/dist/types/boot/runners/memdir.test.d.ts +0 -12
- package/dist/types/boot/runners/oneshot-runner.d.ts +0 -19
- package/dist/types/boot/runners/read-state.d.ts +0 -82
- package/dist/types/boot/runners/read-state.test.d.ts +0 -10
- package/dist/types/boot/runners/registry.d.ts +0 -30
- package/dist/types/boot/runners/repl-runner.d.ts +0 -19
- package/dist/types/boot/runners/session-persist.test.d.ts +0 -10
- package/dist/types/boot/runners/session.d.ts +0 -65
- package/dist/types/boot/runners/session.test.d.ts +0 -10
- package/dist/types/boot/stages.d.ts +0 -92
- package/dist/types/boot/upgrade/apply.d.ts +0 -45
- package/dist/types/boot/upgrade/index.d.ts +0 -13
- package/dist/types/boot/upgrade/upgrades.d.ts +0 -126
- package/dist/types/briefing/briefing.test.d.ts +0 -15
- package/dist/types/briefing/compose.d.ts +0 -37
- package/dist/types/briefing/context-docs.d.ts +0 -38
- package/dist/types/briefing/context-docs.test.d.ts +0 -18
- package/dist/types/briefing/contract.d.ts +0 -686
- package/dist/types/briefing/index.d.ts +0 -29
- package/dist/types/briefing/macros.d.ts +0 -206
- package/dist/types/briefing/skills.d.ts +0 -67
- package/dist/types/capability-deck/bridge-ledger/index.d.ts +0 -25
- package/dist/types/capability-deck/bridge-ledger/key.d.ts +0 -65
- package/dist/types/capability-deck/bridge-ledger/ledger.d.ts +0 -129
- package/dist/types/capability-deck/bridge-ledger/network.d.ts +0 -115
- package/dist/types/capability-deck/builtin-bridge.d.ts +0 -114
- package/dist/types/capability-deck/capability-deck.test.d.ts +0 -18
- package/dist/types/capability-deck/cards/bg-process-card.d.ts +0 -99
- package/dist/types/capability-deck/cards/index.d.ts +0 -37
- package/dist/types/capability-deck/cards/memory-card.d.ts +0 -68
- package/dist/types/capability-deck/cards/plan-file.d.ts +0 -56
- package/dist/types/capability-deck/cards/plan-tools.d.ts +0 -97
- package/dist/types/capability-deck/cards/plan-tools.test.d.ts +0 -9
- package/dist/types/capability-deck/cards/saas-card.d.ts +0 -78
- package/dist/types/capability-deck/cards/task-card.d.ts +0 -106
- package/dist/types/capability-deck/cards/todo-card.d.ts +0 -78
- package/dist/types/capability-deck/cards/workflow-card.d.ts +0 -55
- package/dist/types/capability-deck/cards/workflow-card.test.d.ts +0 -12
- package/dist/types/capability-deck/checkpoint.int.test.d.ts +0 -25
- package/dist/types/capability-deck/contract.d.ts +0 -317
- package/dist/types/capability-deck/index.d.ts +0 -46
- package/dist/types/capability-deck/manifest.d.ts +0 -60
- package/dist/types/capability-deck/provision.d.ts +0 -76
- package/dist/types/capability-deck/read-edit-gate.int.test.d.ts +0 -21
- package/dist/types/channels/channels.test.d.ts +0 -15
- package/dist/types/channels/contract.d.ts +0 -489
- package/dist/types/channels/framer.d.ts +0 -49
- package/dist/types/channels/index.d.ts +0 -24
- package/dist/types/channels/link/dialog.d.ts +0 -138
- package/dist/types/channels/link/driver.d.ts +0 -81
- package/dist/types/channels/link/index.d.ts +0 -13
- package/dist/types/channels/link/server.d.ts +0 -70
- package/dist/types/channels/oneshot.d.ts +0 -37
- package/dist/types/channels/ops.d.ts +0 -89
- package/dist/types/channels/session-ops.d.ts +0 -80
- package/dist/types/conductor/bash-guard.d.ts +0 -106
- package/dist/types/conductor/bash-guard.test.d.ts +0 -17
- package/dist/types/conductor/catalog/catalog.d.ts +0 -87
- package/dist/types/conductor/catalog/index.d.ts +0 -14
- package/dist/types/conductor/catalog/matcher.d.ts +0 -47
- package/dist/types/conductor/conductor.d.ts +0 -189
- package/dist/types/conductor/conductor.test.d.ts +0 -10
- package/dist/types/conductor/contract.d.ts +0 -774
- package/dist/types/conductor/diagnostics.d.ts +0 -183
- package/dist/types/conductor/diagnostics.test.d.ts +0 -10
- package/dist/types/conductor/index.d.ts +0 -26
- package/dist/types/conductor/permission-gate.integration.test.d.ts +0 -22
- package/dist/types/conductor/permission-wiring.test.d.ts +0 -14
- package/dist/types/conductor/permissions.d.ts +0 -217
- package/dist/types/conductor/permissions.test.d.ts +0 -12
- package/dist/types/conductor/plan-mode.integration.test.d.ts +0 -23
- package/dist/types/conductor/post-edit-diagnostics.test.d.ts +0 -13
- package/dist/types/conductor/signal-hub/hub.d.ts +0 -83
- package/dist/types/conductor/signal-hub/index.d.ts +0 -19
- package/dist/types/conductor/signal-hub/translate.d.ts +0 -77
- package/dist/types/conductor/skill-parse/index.d.ts +0 -10
- package/dist/types/conductor/skill-parse/parse.d.ts +0 -67
- package/dist/types/conductor/submit.test.d.ts +0 -28
- package/dist/types/conductor/transcript-store/index.d.ts +0 -16
- package/dist/types/conductor/transcript-store/serialize.d.ts +0 -106
- package/dist/types/conductor/transcript-store/serialize.test.d.ts +0 -10
- package/dist/types/conductor/transcript-store/store.d.ts +0 -188
- package/dist/types/console/components/AgentsView.d.ts +0 -41
- package/dist/types/console/components/BackgroundAgents.d.ts +0 -63
- package/dist/types/console/components/BackgroundAgents.test.d.ts +0 -8
- package/dist/types/console/components/Banner.d.ts +0 -110
- package/dist/types/console/components/Composer.d.ts +0 -37
- package/dist/types/console/components/StatusBar.d.ts +0 -42
- package/dist/types/console/components/TerminalConsole.d.ts +0 -32
- package/dist/types/console/components/WorkingIndicator.d.ts +0 -44
- package/dist/types/console/components/WorkingIndicator.test.d.ts +0 -9
- package/dist/types/console/components/banner-sweep.d.ts +0 -55
- package/dist/types/console/components/banner.test.d.ts +0 -9
- package/dist/types/console/components/welcome.d.ts +0 -115
- package/dist/types/console/components/welcome.test.d.ts +0 -9
- package/dist/types/console/console.test.d.ts +0 -19
- package/dist/types/console/contract.d.ts +0 -598
- package/dist/types/console/index.d.ts +0 -34
- package/dist/types/console/input/complete.d.ts +0 -120
- package/dist/types/console/input/dir-reader.d.ts +0 -28
- package/dist/types/console/input/index.d.ts +0 -24
- package/dist/types/console/input/input.test.d.ts +0 -14
- package/dist/types/console/input/keymap.d.ts +0 -193
- package/dist/types/console/input/paste.d.ts +0 -131
- package/dist/types/console/mount.d.ts +0 -53
- package/dist/types/console/overlays/approval-queue.d.ts +0 -71
- package/dist/types/console/overlays/approval.d.ts +0 -104
- package/dist/types/console/overlays/approval.test.d.ts +0 -17
- package/dist/types/console/overlays/auth.d.ts +0 -31
- package/dist/types/console/overlays/boards.d.ts +0 -55
- package/dist/types/console/overlays/host.d.ts +0 -45
- package/dist/types/console/overlays/index.d.ts +0 -15
- package/dist/types/console/overlays/pickers.d.ts +0 -37
- package/dist/types/console/overlays/sessions.d.ts +0 -29
- package/dist/types/console/reducer.d.ts +0 -51
- package/dist/types/console/slash/builtins.d.ts +0 -33
- package/dist/types/console/slash/commands/dynamic.d.ts +0 -57
- package/dist/types/console/slash/commands/dynamic.test.d.ts +0 -9
- package/dist/types/console/slash/commands/integrations.d.ts +0 -28
- package/dist/types/console/slash/commands/integrations.test.d.ts +0 -18
- package/dist/types/console/slash/commands/shared.d.ts +0 -72
- package/dist/types/console/slash/commands/transcript.d.ts +0 -24
- package/dist/types/console/slash/commands/transcript.test.d.ts +0 -10
- package/dist/types/console/slash/commands/workbench.d.ts +0 -21
- package/dist/types/console/slash/commands/workbench.test.d.ts +0 -10
- package/dist/types/console/slash/index.d.ts +0 -34
- package/dist/types/console/slash/registry.d.ts +0 -90
- package/dist/types/console/slash/resolve.d.ts +0 -109
- package/dist/types/console/slash/slash.test.d.ts +0 -18
- package/dist/types/console/startup.d.ts +0 -119
- package/dist/types/console/theme/adapter.d.ts +0 -79
- package/dist/types/console/theme/index.d.ts +0 -18
- package/dist/types/console/theme/palette.d.ts +0 -77
- package/dist/types/console/theme/resolve.d.ts +0 -45
- package/dist/types/console/theme/theme.test.d.ts +0 -16
- package/dist/types/console/theme/tokens.d.ts +0 -62
- package/dist/types/entry.d.ts +0 -17
- package/dist/types/guardrails.d.ts +0 -33
- package/dist/types/index.d.ts +0 -24
- package/dist/types/insight/channel.d.ts +0 -45
- package/dist/types/insight/contract.d.ts +0 -411
- package/dist/types/insight/index.d.ts +0 -26
- package/dist/types/insight/insight.test.d.ts +0 -17
- package/dist/types/insight/recorder.d.ts +0 -63
- package/dist/types/insight/redaction.d.ts +0 -44
- package/dist/types/insight/replay.d.ts +0 -77
- package/dist/types/insight/sampling.d.ts +0 -84
- package/dist/types/insight/serialize.d.ts +0 -54
- package/dist/types/insight/sinks/console.d.ts +0 -36
- package/dist/types/insight/sinks/file.d.ts +0 -37
- package/dist/types/insight/sinks/index.d.ts +0 -16
- package/dist/types/insight/sinks/stream.d.ts +0 -53
- package/dist/types/kit/clipboard-image.d.ts +0 -40
- package/dist/types/kit/external-editor.d.ts +0 -35
- package/dist/types/kit/image.d.ts +0 -102
- package/dist/types/kit/index.d.ts +0 -29
- package/dist/types/kit/kit.test.d.ts +0 -13
- package/dist/types/kit/shell.d.ts +0 -50
- package/dist/types/kit/tool-fetch.d.ts +0 -165
- package/dist/types/launch/catalog.d.ts +0 -51
- package/dist/types/launch/contract.d.ts +0 -387
- package/dist/types/launch/credentials.d.ts +0 -112
- package/dist/types/launch/index.d.ts +0 -28
- package/dist/types/launch/invocation/attachments.d.ts +0 -72
- package/dist/types/launch/invocation/flags.d.ts +0 -59
- package/dist/types/launch/invocation/index.d.ts +0 -23
- package/dist/types/launch/invocation/read.d.ts +0 -52
- package/dist/types/launch/invocation/usage.d.ts +0 -25
- package/dist/types/launch/launch.test.d.ts +0 -20
- package/dist/types/launch/oauth.d.ts +0 -101
- package/dist/types/launch/packages.d.ts +0 -75
- package/dist/types/launch/packages.test.d.ts +0 -15
- package/dist/types/launch/pickers.d.ts +0 -97
- package/dist/types/runtime-bridge/bridges/_drive.d.ts +0 -74
- package/dist/types/runtime-bridge/bridges/builtins.d.ts +0 -77
- package/dist/types/runtime-bridge/bridges/claude-cli.d.ts +0 -37
- package/dist/types/runtime-bridge/bridges/codex-cli.d.ts +0 -27
- package/dist/types/runtime-bridge/bridges/index.d.ts +0 -15
- package/dist/types/runtime-bridge/bridges/indusagi-cli.d.ts +0 -36
- package/dist/types/runtime-bridge/broker.d.ts +0 -182
- package/dist/types/runtime-bridge/contract.d.ts +0 -436
- package/dist/types/runtime-bridge/index.d.ts +0 -21
- package/dist/types/runtime-bridge/runtime-bridge.test.d.ts +0 -17
- package/dist/types/runtime-bridge/sink.d.ts +0 -59
- package/dist/types/sessions/contract.d.ts +0 -79
- package/dist/types/sessions/index.d.ts +0 -11
- package/dist/types/sessions/library.d.ts +0 -95
- package/dist/types/sessions/sessions.test.d.ts +0 -11
- package/dist/types/settings/contract.d.ts +0 -175
- package/dist/types/settings/index.d.ts +0 -13
- package/dist/types/settings/manager.d.ts +0 -109
- package/dist/types/settings/settings.test.d.ts +0 -16
- package/dist/types/transcript-export/index.d.ts +0 -20
- package/dist/types/transcript-export/publish.d.ts +0 -81
- package/dist/types/transcript-export/sgr.d.ts +0 -90
- package/dist/types/transcript-export/template.d.ts +0 -64
- package/dist/types/transcript-export/theme-bridge.d.ts +0 -99
- package/dist/types/transcript-export/transcript-export.test.d.ts +0 -16
- package/dist/types/window-budget/budget/estimate.d.ts +0 -47
- package/dist/types/window-budget/budget/gate.d.ts +0 -37
- package/dist/types/window-budget/budget/index.d.ts +0 -14
- package/dist/types/window-budget/budget/slice.d.ts +0 -38
- package/dist/types/window-budget/condenser.d.ts +0 -73
- package/dist/types/window-budget/contract.d.ts +0 -182
- package/dist/types/window-budget/index.d.ts +0 -17
- package/dist/types/window-budget/microcompact.d.ts +0 -68
- package/dist/types/window-budget/microcompact.test.d.ts +0 -16
- package/dist/types/window-budget/rehydrate.d.ts +0 -56
- package/dist/types/window-budget/summarize/condense.d.ts +0 -70
- package/dist/types/window-budget/summarize/index.d.ts +0 -12
- package/dist/types/window-budget/summarize/prompt.d.ts +0 -56
- package/dist/types/window-budget/window-budget.test.d.ts +0 -18
- package/dist/types/workflow-engine/agent-runner.d.ts +0 -105
- package/dist/types/workflow-engine/agent-runner.test.d.ts +0 -8
- package/dist/types/workflow-engine/display.d.ts +0 -148
- package/dist/types/workflow-engine/display.test.d.ts +0 -1
- package/dist/types/workflow-engine/engine.d.ts +0 -183
- package/dist/types/workflow-engine/engine.test.d.ts +0 -1
- package/dist/types/workflow-engine/index.d.ts +0 -21
- package/dist/types/workflow-engine/parse.d.ts +0 -64
- package/dist/types/workflow-engine/parse.test.d.ts +0 -1
- package/dist/types/workflow-engine/structured-output.d.ts +0 -51
- package/dist/types/workflow-engine/structured-output.test.d.ts +0 -1
- package/dist/types/workspace/brand.d.ts +0 -26
- package/dist/types/workspace/index.d.ts +0 -11
- package/dist/types/workspace/locator.d.ts +0 -50
- package/dist/types/workspace/runtime-detect.d.ts +0 -56
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Window-budget contract — the FROZEN type surface of the context-window
|
|
3
|
-
* budgeting subsystem (Phase 3, subsystem 05).
|
|
4
|
-
*
|
|
5
|
-
* A long-running coding session accrues messages — user turns, assistant turns,
|
|
6
|
-
* tool calls and their results — until the transcript approaches the model's
|
|
7
|
-
* context window. This subsystem keeps the session usable by *condensing* older
|
|
8
|
-
* history into a single structured summary message while keeping a verbatim
|
|
9
|
-
* tail of the most-recent turns. It answers three questions:
|
|
10
|
-
*
|
|
11
|
-
* 1. **Budget** — *when* are we over budget? A {@link BudgetPolicy} carries
|
|
12
|
-
* config-sourced thresholds (no magic literals); {@link isOverBudget}
|
|
13
|
-
* decides from a real {@link TokenEstimate}.
|
|
14
|
-
* 2. **Slice** — *where* do we cut? {@link planSlice} computes a
|
|
15
|
-
* {@link CondensePlan} via a forward prefix-sum + binary search over a
|
|
16
|
-
* cumulative-token array, never splitting a tool_call from its tool_result.
|
|
17
|
-
* 3. **Condense** — *how* do we compress the dropped portion? A
|
|
18
|
-
* {@link Condenser} flattens the dropped messages, asks an injectable model
|
|
19
|
-
* completer for a structured {@link Summary}, and returns the rebuilt
|
|
20
|
-
* transcript (summary + kept tail).
|
|
21
|
-
*
|
|
22
|
-
* This file declares *only* shapes plus the function-type seams — no behavior,
|
|
23
|
-
* no I/O, no prompt strings. Every later window-budget module (the meter, the
|
|
24
|
-
* slice planner, the condenser, the branch archivist, the prompt templates, and
|
|
25
|
-
* the public barrel) is written against the names declared here.
|
|
26
|
-
*
|
|
27
|
-
* Design stance:
|
|
28
|
-
* - Thresholds are **configuration, not constants**. {@link BudgetPolicy}
|
|
29
|
-
* fields are supplied by the caller; this module bakes in no fixed token
|
|
30
|
-
* fingerprints. Defaults, if any, live in the implementation and are
|
|
31
|
-
* computed relative to the model's own context window.
|
|
32
|
-
* - Branch-summarization is **not a separate engine**. It collapses into the
|
|
33
|
-
* condenser behind a {@link CondenseScope} flag (`"session" | "branch"`),
|
|
34
|
-
* so there is one prompt-assembly path, one token estimator, one slicer.
|
|
35
|
-
* - The model completer is **injectable** ({@link CompleteFn}, default the
|
|
36
|
-
* framework's `completeSimple`) so the condenser runs in tests with no
|
|
37
|
-
* network.
|
|
38
|
-
* - The produced condenser is **conductor-consumable**: a {@link Condenser}
|
|
39
|
-
* is structurally a conductor `CondenseFn`
|
|
40
|
-
* (`(messages: AgentMessage[]) => AgentMessage[] | Promise<AgentMessage[]>`),
|
|
41
|
-
* so a {@link CondenserDeps}-built condenser plugs straight into the
|
|
42
|
-
* conductor's auto-compaction seam.
|
|
43
|
-
*
|
|
44
|
-
* Framework anchors (all from the `indusagi` package — the sibling rebuilt
|
|
45
|
-
* framework this app targets):
|
|
46
|
-
* - `AgentMessage` ← `indusagi/agent`
|
|
47
|
-
* - `Model`, `Usage`, `completeSimple` (and its `Api`/`AssistantMessage`/
|
|
48
|
-
* `Context`/`SimpleStreamOptions`/`StreamLogger` shapes) ← `indusagi/ai`
|
|
49
|
-
*
|
|
50
|
-
* This module never re-declares these; it composes them.
|
|
51
|
-
*/
|
|
52
|
-
import type { AgentMessage } from "indusagi/agent";
|
|
53
|
-
import type { Api, AssistantMessage, Context, Model, SimpleStreamOptions, StreamLogger, Usage } from "indusagi/ai";
|
|
54
|
-
/** Re-exported framework vocabulary window-budget consumers routinely need. */
|
|
55
|
-
export type { AgentMessage, Model, Usage };
|
|
56
|
-
/**
|
|
57
|
-
* The config-sourced thresholds that govern when and how the transcript is
|
|
58
|
-
* condensed. Every field is a *number the caller supplies* — there are no magic
|
|
59
|
-
* token literals baked into this contract. An implementation may
|
|
60
|
-
* provide defaults, but they are configuration values, not protected constants,
|
|
61
|
-
* and deliberately differ from the legacy fingerprints.
|
|
62
|
-
*/
|
|
63
|
-
export interface BudgetPolicy {
|
|
64
|
-
/**
|
|
65
|
-
* Fraction of the model's `contextWindow` at which condensing is triggered,
|
|
66
|
-
* in `(0, 1]`. The meter is "over budget" once the estimated context tokens
|
|
67
|
-
* cross `contextWindow * triggerRatio`. Expressing the trigger as a ratio
|
|
68
|
-
* (rather than an absolute reserve) keeps it window-relative and free of
|
|
69
|
-
* baked-in token counts.
|
|
70
|
-
*/
|
|
71
|
-
readonly triggerRatio: number;
|
|
72
|
-
/**
|
|
73
|
-
* How much of the recent transcript to keep verbatim, measured in estimated
|
|
74
|
-
* tokens. The slice planner preserves a tail of at least this many tokens
|
|
75
|
-
* (snapped to a legal boundary) and condenses everything before it.
|
|
76
|
-
*/
|
|
77
|
-
readonly keepRecent: number;
|
|
78
|
-
/**
|
|
79
|
-
* Optional token headroom to subtract from the window before the trigger is
|
|
80
|
-
* evaluated — a safety margin so a condense fires *before* the very next turn
|
|
81
|
-
* would overflow. When omitted, only {@link triggerRatio} governs the trigger.
|
|
82
|
-
*/
|
|
83
|
-
readonly reserveTokens?: number;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* The outcome of measuring a transcript against a model's window. Anchors on the
|
|
87
|
-
* provider's authoritative `usage` count when available (`anchored: true`) and
|
|
88
|
-
* falls back to a rough char/role estimate otherwise; either way `contextTokens`
|
|
89
|
-
* is the figure {@link isOverBudget} compares to `contextWindow`.
|
|
90
|
-
*/
|
|
91
|
-
export interface TokenEstimate {
|
|
92
|
-
/** Best estimate of tokens currently occupying the context window. */
|
|
93
|
-
readonly contextTokens: number;
|
|
94
|
-
/** The model's total context window, in tokens (`Model.contextWindow`). */
|
|
95
|
-
readonly contextWindow: number;
|
|
96
|
-
/**
|
|
97
|
-
* `true` when {@link contextTokens} is anchored on a real provider `usage`
|
|
98
|
-
* figure (only trailing, post-usage messages are estimated); `false` when the
|
|
99
|
-
* whole figure is a heuristic estimate.
|
|
100
|
-
*/
|
|
101
|
-
readonly anchored: boolean;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* The pre-computed result of {@link planSlice}: the chosen cut index and the
|
|
105
|
-
* resulting partition of the transcript.
|
|
106
|
-
*
|
|
107
|
-
* The cut is found by a *forward* prefix-sum + binary search: build a cumulative
|
|
108
|
-
* estimated-token array over the messages, binary-search for the boundary index
|
|
109
|
-
* nearest `total - keepRecent`, then nudge to the closest *legal* boundary —
|
|
110
|
-
* never landing between a `toolCall` and its `toolResult`.
|
|
111
|
-
*
|
|
112
|
-
* Invariants:
|
|
113
|
-
* - `kept.length + dropped.length === messages.length`
|
|
114
|
-
* - `dropped` is the prefix `messages[0 .. cut)` (the older slice to condense)
|
|
115
|
-
* - `kept` is the suffix `messages[cut ..]` (the verbatim recent tail)
|
|
116
|
-
* - `cut` is `0` when nothing is condensable (everything kept).
|
|
117
|
-
*/
|
|
118
|
-
export interface CondensePlan {
|
|
119
|
-
/** Index of the legal cut boundary: `dropped = messages.slice(0, cut)`. */
|
|
120
|
-
readonly cut: number;
|
|
121
|
-
/** The verbatim recent tail preserved as-is (`messages.slice(cut)`). */
|
|
122
|
-
readonly kept: AgentMessage[];
|
|
123
|
-
/** The older slice to be folded into a {@link Summary} (`messages.slice(0, cut)`). */
|
|
124
|
-
readonly dropped: AgentMessage[];
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Which kind of condensing run this is — the flag that collapses
|
|
128
|
-
* branch-summarization into the single condenser path:
|
|
129
|
-
* - `"session"` — condense the *active* transcript in place (the trigger /
|
|
130
|
-
* overflow path); keeps a recent tail, summarizes the head.
|
|
131
|
-
* - `"branch"` — archive an *abandoned* branch into one summary message so its
|
|
132
|
-
* context isn't lost on tree navigation; no verbatim tail is retained.
|
|
133
|
-
*/
|
|
134
|
-
export type CondenseScope = "session" | "branch";
|
|
135
|
-
/**
|
|
136
|
-
* The structured result of summarizing a slice of dropped messages: a single
|
|
137
|
-
* synthetic {@link AgentMessage} that stands in for the messages it covers.
|
|
138
|
-
*/
|
|
139
|
-
export interface Summary {
|
|
140
|
-
/** The synthetic summary message to splice into the rebuilt transcript. */
|
|
141
|
-
readonly message: AgentMessage;
|
|
142
|
-
/** How many source messages this summary replaces. */
|
|
143
|
-
readonly coveredCount: number;
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* The injectable model-completion function. Structurally identical to the
|
|
147
|
-
* framework's `completeSimple`, so the real `completeSimple` is the drop-in
|
|
148
|
-
* default and a test can pass a no-network stub of the same shape. The
|
|
149
|
-
* condenser uses this single call to turn flattened transcript text into a
|
|
150
|
-
* {@link Summary}.
|
|
151
|
-
*/
|
|
152
|
-
export type CompleteFn = <TApi extends Api>(model: Model<TApi>, context: Context, options?: SimpleStreamOptions, logger?: StreamLogger) => Promise<AssistantMessage>;
|
|
153
|
-
/**
|
|
154
|
-
* A condenser: takes the active branch's messages and returns the rebuilt
|
|
155
|
-
* transcript (condensed head + verbatim tail, or the input unchanged when there
|
|
156
|
-
* is nothing to do).
|
|
157
|
-
*
|
|
158
|
-
* This type is **structurally compatible with the conductor's `CondenseFn`**
|
|
159
|
-
* (`(messages: AgentMessage[]) => AgentMessage[] | Promise<AgentMessage[]>`), so
|
|
160
|
-
* the result of the condenser factory plugs directly into the conductor's
|
|
161
|
-
* auto-compaction seam with no adapter.
|
|
162
|
-
*/
|
|
163
|
-
export type Condenser = (messages: AgentMessage[]) => AgentMessage[] | Promise<AgentMessage[]>;
|
|
164
|
-
/**
|
|
165
|
-
* Dependencies for building a {@link Condenser}. All fields are optional so a
|
|
166
|
-
* bare `createCondenser()` yields a working, network-free-testable condenser:
|
|
167
|
-
* - `complete` defaults to the framework's `completeSimple`.
|
|
168
|
-
* - `policy` defaults to the implementation's config-sourced thresholds.
|
|
169
|
-
* - `model` is the summarization model; when omitted the condenser may fall
|
|
170
|
-
* back to a no-op (return input unchanged) rather than guess a model.
|
|
171
|
-
*/
|
|
172
|
-
export interface CondenserDeps {
|
|
173
|
-
/**
|
|
174
|
-
* The injectable model completer (default: framework `completeSimple`). Inject
|
|
175
|
-
* a stub of {@link CompleteFn} shape to run the condenser with no network.
|
|
176
|
-
*/
|
|
177
|
-
readonly complete?: CompleteFn;
|
|
178
|
-
/** The model used to write the summary. When omitted, condensing is a no-op. */
|
|
179
|
-
readonly model?: Model<Api>;
|
|
180
|
-
/** The config-sourced budget thresholds (default: implementation defaults). */
|
|
181
|
-
readonly policy?: BudgetPolicy;
|
|
182
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Window-budget — public barrel.
|
|
3
|
-
*
|
|
4
|
-
* The context-window budgeting subsystem: token measurement, slice planning,
|
|
5
|
-
* and transcript condensing (with branch-archival collapsed in behind a scope
|
|
6
|
-
* flag). Re-exports the frozen contract types plus the live functions: the
|
|
7
|
-
* budget math (estimateTokens / isOverBudget / planSlice), the summarization core
|
|
8
|
-
* (summarize / condenseScope), and the conductor-consumable condenser factory
|
|
9
|
-
* (createCondenser / condense).
|
|
10
|
-
*/
|
|
11
|
-
export type { AgentMessage, BudgetPolicy, CompleteFn, CondensePlan, Condenser, CondenserDeps, CondenseScope, Model, Summary, TokenEstimate, Usage, } from "./contract.js";
|
|
12
|
-
export { budgetLimit, estimateMessageTokens, estimateTokens, isOverBudget, planSlice, prefixTokens, } from "./budget/index.js";
|
|
13
|
-
export { buildSummaryPrompt, CONDENSER_BRIEF, flattenTranscript, summarize, } from "./summarize/index.js";
|
|
14
|
-
export type { SummarizeDeps } from "./summarize/index.js";
|
|
15
|
-
export { AUTO_CONDENSE_POLICY, condense, condenseScope, createCondenser } from "./condenser.js";
|
|
16
|
-
export { CLEARED_TOOL_RESULT, clearStaleToolResults, COMPACTABLE_TOOL_NAMES, } from "./microcompact.js";
|
|
17
|
-
export { rehydrateRecentReads, RESTORED_FILE_PREFIX } from "./rehydrate.js";
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Window-budget / microcompact — clear stale tool-result bodies in place.
|
|
3
|
-
*
|
|
4
|
-
* The cheapest token to reclaim is one that is already dead weight: the verbatim
|
|
5
|
-
* body of a tool result the model has long since acted on. Once an agent has
|
|
6
|
-
* read a file, run a search, or executed a command and moved several turns past
|
|
7
|
-
* it, the full body of that result rarely needs to stay in the window — the
|
|
8
|
-
* model's subsequent reasoning already captured what mattered. Yet those bodies
|
|
9
|
-
* (a 2,000-line `read`, a noisy `bash` log, a wide `grep`) dominate the token
|
|
10
|
-
* budget.
|
|
11
|
-
*
|
|
12
|
-
* **Microcompaction** runs *before* a full {@link condense}: it walks the
|
|
13
|
-
* transcript, keeps the last few tool results verbatim (the model may still be
|
|
14
|
-
* working with them), and replaces the body of every older compactable tool
|
|
15
|
-
* result with a short sentinel. This reclaims tokens for free — no model call,
|
|
16
|
-
* no summary round-trip — and often defers (or shrinks the input to) the real
|
|
17
|
-
* condense.
|
|
18
|
-
*
|
|
19
|
-
* Shape note (this rebuild): a tool result is its OWN top-level
|
|
20
|
-
* {@link ToolResultMessage} (`role: 'toolResult'`), not a block nested inside a
|
|
21
|
-
* user message. Clearing one therefore means replacing *that message's*
|
|
22
|
-
* `content` array with a single sentinel text block — never editing a sub-block
|
|
23
|
-
* of some other message. We only clear results whose owning assistant `toolCall`
|
|
24
|
-
* named a compactable tool, so structural/control results stay intact.
|
|
25
|
-
*
|
|
26
|
-
* Behavior-preserving by construction: when there is nothing to clear (no
|
|
27
|
-
* compactable results, or every one is within the keep window) the *same input
|
|
28
|
-
* reference* is returned, so a caller can cheaply detect a no-op.
|
|
29
|
-
*/
|
|
30
|
-
import type { AgentMessage } from "./contract.js";
|
|
31
|
-
/**
|
|
32
|
-
* The placeholder spliced in where a stale tool-result body used to be. Kept
|
|
33
|
-
* short on purpose — the whole point is to reclaim the tokens the original body
|
|
34
|
-
* occupied — while still signalling to the model (and to a human reading the
|
|
35
|
-
* transcript) that real content was elided rather than lost.
|
|
36
|
-
*/
|
|
37
|
-
export declare const CLEARED_TOOL_RESULT = "[Old tool result content cleared]";
|
|
38
|
-
/**
|
|
39
|
-
* The wire names of tools whose results are safe to clear once stale.
|
|
40
|
-
*
|
|
41
|
-
* These are the read-mostly / output-heavy tools whose bodies are reconstructable
|
|
42
|
-
* (re-read the file, re-run the search) and whose stale content the model has
|
|
43
|
-
* already digested. Control/state tools (todo, memory, task) are deliberately
|
|
44
|
-
* absent — their results can carry standing instructions the model still needs.
|
|
45
|
-
*/
|
|
46
|
-
export declare const COMPACTABLE_TOOL_NAMES: ReadonlySet<string>;
|
|
47
|
-
/**
|
|
48
|
-
* Clear the bodies of stale compactable tool results, keeping the most recent
|
|
49
|
-
* `keepRecent` of them verbatim.
|
|
50
|
-
*
|
|
51
|
-
* Walks the transcript, identifies every `role:'toolResult'` message that
|
|
52
|
-
* belongs to a compactable tool call, keeps the last `keepRecent` (floored at 1
|
|
53
|
-
* — `slice(-0)` would keep everything), and replaces each older one's `content`
|
|
54
|
-
* with a single `{ type:'text', text: CLEARED_TOOL_RESULT }` block. Non-tool
|
|
55
|
-
* messages, control-tool results, and already-cleared results are left exactly
|
|
56
|
-
* as they were.
|
|
57
|
-
*
|
|
58
|
-
* Returns the **same input array reference** when nothing was cleared, so the
|
|
59
|
-
* caller can detect a no-op by identity. Otherwise returns a new array; cleared
|
|
60
|
-
* messages are fresh objects (the originals are not mutated).
|
|
61
|
-
*
|
|
62
|
-
* @param messages the active transcript, oldest-first
|
|
63
|
-
* @param opts.keepRecent how many most-recent compactable results to keep
|
|
64
|
-
* verbatim (default {@link DEFAULT_KEEP_RECENT}, floored at 1)
|
|
65
|
-
*/
|
|
66
|
-
export declare function clearStaleToolResults(messages: AgentMessage[], opts?: {
|
|
67
|
-
keepRecent?: number;
|
|
68
|
-
}): AgentMessage[];
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Window-budget / microcompact + rehydrate — unit tests for item #18.
|
|
3
|
-
*
|
|
4
|
-
* Three layers ride the condense path:
|
|
5
|
-
* 1. microcompact ({@link clearStaleToolResults}) — blank older completed
|
|
6
|
-
* tool-result bodies to a sentinel, keeping the last N verbatim; no-op
|
|
7
|
-
* (same reference) otherwise.
|
|
8
|
-
* 2. rehydration ({@link rehydrateRecentReads}) — re-attach the most-recently
|
|
9
|
-
* dropped file reads as synthetic user messages, deduped against the kept
|
|
10
|
-
* tail, honoring maxFiles / tokenBudget.
|
|
11
|
-
* 3. circuit breaker — covered in the conductor suite (3 throwing condense
|
|
12
|
-
* calls stop further attempts, a success resets).
|
|
13
|
-
*
|
|
14
|
-
* Pure + network-free: no model is bound anywhere here.
|
|
15
|
-
*/
|
|
16
|
-
export {};
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Window-budget / rehydrate — re-attach recently-read files after a condense.
|
|
3
|
-
*
|
|
4
|
-
* A full {@link condense} folds the dropped head of the transcript into one
|
|
5
|
-
* summary message. That digest captures *what happened*, but it necessarily
|
|
6
|
-
* loses the verbatim bodies of files the agent had just read — and those bodies
|
|
7
|
-
* are often exactly the working context the next turn needs (the file it was
|
|
8
|
-
* mid-edit on, the config it was reasoning about). Re-reading them costs a tool
|
|
9
|
-
* round-trip and, worse, the model may not realize it needs to.
|
|
10
|
-
*
|
|
11
|
-
* **Post-compact rehydration** softens that cliff: after the slice is dropped,
|
|
12
|
-
* it scans the *dropped* messages for `read` results, takes the most-recent
|
|
13
|
-
* handful that aren't already visible in the kept tail, and re-attaches their
|
|
14
|
-
* bodies as synthetic user messages ("[Restored file after compaction] …") under
|
|
15
|
-
* a token budget. The model keeps its working files without a re-read, while the
|
|
16
|
-
* older surrounding chatter still gets compressed away.
|
|
17
|
-
*
|
|
18
|
-
* Shape note (this rebuild): a read's *body* lives in its own top-level
|
|
19
|
-
* {@link ToolResultMessage} (`role:'toolResult'`), and the read's *path* lives in
|
|
20
|
-
* the owning assistant `toolCall.arguments.path` (the read tool's arg is `path`,
|
|
21
|
-
* not `file_path`). We pair each dropped `read` call with its result by
|
|
22
|
-
* `toolCallId`, dedup against paths still visible in the kept tail, and emit the
|
|
23
|
-
* most-recent survivors under a token cap.
|
|
24
|
-
*
|
|
25
|
-
* Behavior-preserving by construction: returns an empty array whenever there is
|
|
26
|
-
* nothing to restore (no dropped reads, all already visible, or the budget is
|
|
27
|
-
* exhausted), so the caller can splice the result unconditionally.
|
|
28
|
-
*/
|
|
29
|
-
import type { AgentMessage } from "./contract.js";
|
|
30
|
-
/** Prefix marking a synthetic message that restores a file body post-compaction. */
|
|
31
|
-
export declare const RESTORED_FILE_PREFIX = "[Restored file after compaction]";
|
|
32
|
-
/**
|
|
33
|
-
* Build the synthetic user messages that re-attach the most-recently-read files
|
|
34
|
-
* dropped by a condense.
|
|
35
|
-
*
|
|
36
|
-
* Scans `dropped` for `read` calls + result bodies, drops any path still visible
|
|
37
|
-
* in `kept`, sorts the survivors most-recent-first, takes up to `maxFiles`, and
|
|
38
|
-
* emits each as a `user` message of the form
|
|
39
|
-
* `"[Restored file after compaction] <path>\n<body>"` — stopping once the running
|
|
40
|
-
* token estimate would exceed `tokenBudget`. The returned messages are ordered
|
|
41
|
-
* oldest-restored-first so they read naturally when spliced after the summary.
|
|
42
|
-
*
|
|
43
|
-
* Returns an **empty array** when nothing is restorable, so the caller can splice
|
|
44
|
-
* the result unconditionally (`[summary, ...restored, ...kept]`).
|
|
45
|
-
*
|
|
46
|
-
* @param dropped the condensed-away head slice (original bodies, pre-summary)
|
|
47
|
-
* @param kept the verbatim tail that survives the condense
|
|
48
|
-
* @param opts.maxFiles cap on restored files (default {@link DEFAULT_MAX_FILES})
|
|
49
|
-
* @param opts.tokenBudget token ceiling for the restored block (default {@link DEFAULT_TOKEN_BUDGET})
|
|
50
|
-
* @param opts.readToolName wire name of the read tool (default `"read"`)
|
|
51
|
-
*/
|
|
52
|
-
export declare function rehydrateRecentReads(dropped: AgentMessage[], kept: AgentMessage[], opts?: {
|
|
53
|
-
maxFiles?: number;
|
|
54
|
-
tokenBudget?: number;
|
|
55
|
-
readToolName?: string;
|
|
56
|
-
}): AgentMessage[];
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Window-budget — model-driven summarization.
|
|
3
|
-
*
|
|
4
|
-
* {@link summarize} is the single condensing primitive: given the dropped prefix
|
|
5
|
-
* of a transcript and a {@link SummarizeDeps} bundle, it flattens those messages,
|
|
6
|
-
* asks the injectable model completer to write a structured digest, and returns a
|
|
7
|
-
* synthetic {@link Summary} message that stands in for the slice it covers.
|
|
8
|
-
*
|
|
9
|
-
* Both condensing scopes flow through this one function:
|
|
10
|
-
* - `"session"` — the active-session checkpoint (head condensed, tail kept by
|
|
11
|
-
* the caller).
|
|
12
|
-
* - `"branch"` — an abandoned branch archived into one message.
|
|
13
|
-
* The only difference is the scope flag forwarded into {@link buildSummaryPrompt}
|
|
14
|
-
* (which selects the framing line). {@link condenseScope} is the thin
|
|
15
|
-
* branch-archival entrypoint that pins `scope: "branch"`.
|
|
16
|
-
*
|
|
17
|
-
* The completer is injectable ({@link SummarizeDeps.complete}, default the
|
|
18
|
-
* framework's `completeSimple`) so tests run with no network — pass a stub that
|
|
19
|
-
* returns a canned {@link AssistantMessage}. When no `model` is supplied there is
|
|
20
|
-
* nothing to call, so {@link summarize} degrades to a deterministic local digest
|
|
21
|
-
* rather than guessing a model — keeping it usable in a bare/offline build.
|
|
22
|
-
*/
|
|
23
|
-
import type { AgentMessage, CompleteFn, CondenseScope, Model, Summary } from "../contract.js";
|
|
24
|
-
import { flattenTranscript } from "./prompt.js";
|
|
25
|
-
/**
|
|
26
|
-
* What {@link summarize} needs. Every field is optional so the function is
|
|
27
|
-
* network-free-testable: omit `model` for a local fallback digest, or inject a
|
|
28
|
-
* `complete` stub for a scripted model response.
|
|
29
|
-
*/
|
|
30
|
-
export interface SummarizeDeps {
|
|
31
|
-
/** Injectable completer (default: framework `completeSimple`). */
|
|
32
|
-
readonly complete?: CompleteFn;
|
|
33
|
-
/** The summarization model. When omitted, a deterministic local digest is used. */
|
|
34
|
-
readonly model?: Model<Model<string>["api"]>;
|
|
35
|
-
/** Which kind of condense this is; defaults to `"session"`. */
|
|
36
|
-
readonly scope?: CondenseScope;
|
|
37
|
-
/** An earlier digest to refresh/extend (iterative-refresh / branch carry-in). */
|
|
38
|
-
readonly priorDigest?: string;
|
|
39
|
-
/** Cancellation signal forwarded to the completer. */
|
|
40
|
-
readonly signal?: AbortSignal;
|
|
41
|
-
/**
|
|
42
|
-
* Optional cap on the digest size, in tokens, forwarded to the completer's
|
|
43
|
-
* `maxTokens`. A modest ceiling keeps the summary itself from eating the
|
|
44
|
-
* window. When omitted the model's own default applies.
|
|
45
|
-
*/
|
|
46
|
-
readonly maxTokens?: number;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Summarize a slice of dropped messages into a single synthetic {@link Summary}.
|
|
50
|
-
*
|
|
51
|
-
* One code path for both scopes — `deps.scope` (default `"session"`) only changes
|
|
52
|
-
* the prompt framing. With a `model` bound it calls `deps.complete`
|
|
53
|
-
* (default `completeSimple`) once with {@link CONDENSER_BRIEF} as the system
|
|
54
|
-
* prompt and {@link buildSummaryPrompt} as the user turn; otherwise it returns a
|
|
55
|
-
* deterministic local digest. Never throws on an empty model reply — it falls
|
|
56
|
-
* back to the local digest so a {@link Summary} is always produced.
|
|
57
|
-
*
|
|
58
|
-
* @returns a {@link Summary} whose `message` replaces the `coveredCount` source
|
|
59
|
-
* messages it summarizes.
|
|
60
|
-
*/
|
|
61
|
-
export declare function summarize(messages: AgentMessage[], deps?: SummarizeDeps): Promise<Summary>;
|
|
62
|
-
/**
|
|
63
|
-
* Branch-archival entrypoint: condense an abandoned branch into one summary
|
|
64
|
-
* message. A thin wrapper that pins `scope: "branch"` and delegates to
|
|
65
|
-
* {@link summarize} — the branch case is the same machinery, not a separate
|
|
66
|
-
* engine.
|
|
67
|
-
*/
|
|
68
|
-
export declare function condenseScope(messages: AgentMessage[], deps?: Omit<SummarizeDeps, "scope">): Promise<Summary>;
|
|
69
|
-
/** Re-export the flattener so callers can preview what the model will receive. */
|
|
70
|
-
export { flattenTranscript };
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Window-budget — summarization subsystem barrel.
|
|
3
|
-
*
|
|
4
|
-
* Model-driven condensing of the dropped transcript prefix into one synthetic
|
|
5
|
-
* summary message, with re-authored prompts (new section names + a new tag
|
|
6
|
-
* vocabulary). Branch-archival folds in behind the scope flag — `condenseScope`
|
|
7
|
-
* is the branch entrypoint over the same `summarize` core.
|
|
8
|
-
*/
|
|
9
|
-
export { buildSummaryPrompt, CONDENSER_BRIEF, flattenTranscript, } from "./prompt.js";
|
|
10
|
-
export { condenseScope, summarize } from "./condense.js";
|
|
11
|
-
export type { SummarizeDeps } from "./condense.js";
|
|
12
|
-
export type { AgentMessage, CompleteFn, CondenseScope, Model, Summary, } from "../contract.js";
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Window-budget — summarization prompt assembly (re-authored).
|
|
3
|
-
*
|
|
4
|
-
* When the transcript crosses budget, the older head is *condensed* into one
|
|
5
|
-
* synthetic message. This module turns the dropped slice of {@link AgentMessage}s
|
|
6
|
-
* into the single text payload handed to the model completer. Two pieces ship
|
|
7
|
-
* here:
|
|
8
|
-
*
|
|
9
|
-
* 1. {@link CONDENSER_BRIEF} — the system-prompt brief that frames the model as
|
|
10
|
-
* a *recorder*, not a continuation of the chat: read the transcript as data
|
|
11
|
-
* and emit only the structured digest.
|
|
12
|
-
* 2. {@link buildSummaryPrompt} — flattens the dropped messages into a tagged
|
|
13
|
-
* block and appends the section template the model fills in.
|
|
14
|
-
*
|
|
15
|
-
* OWN VOCABULARY (an original prompt design):
|
|
16
|
-
* - Section headings are `# Objective / # Guardrails /
|
|
17
|
-
* # Status (Shipped / Active / Stuck) / # Rationale / # Plan / # Carryover`.
|
|
18
|
-
* - The transcript is wrapped in `<scrollback>…</scrollback>` and a prior digest
|
|
19
|
-
* (the branch-archival / iterative-refresh path) in
|
|
20
|
-
* `<carried-digest>…</carried-digest>`.
|
|
21
|
-
* - Per-message lines use `» role:` markers (`» you`, `» agent`,
|
|
22
|
-
* `» agent.plan`, `» agent.call`, `» tool`).
|
|
23
|
-
*
|
|
24
|
-
* No token math, no model calls, no I/O here — only string assembly. The scope
|
|
25
|
-
* flag selects the framing line (active-session checkpoint vs abandoned-branch
|
|
26
|
-
* archive); everything else is one code path.
|
|
27
|
-
*/
|
|
28
|
-
import type { AgentMessage, CondenseScope } from "../contract.js";
|
|
29
|
-
/**
|
|
30
|
-
* The system-prompt brief for the condenser model. Frames the request as a
|
|
31
|
-
* record-keeping task — the model must NOT answer, continue, or act on the
|
|
32
|
-
* conversation; it only transcribes it into the fixed section layout. Re-authored
|
|
33
|
-
* wording; shares no sentences with the legacy `SUMMARIZATION_SYSTEM_PROMPT`.
|
|
34
|
-
*/
|
|
35
|
-
export declare const CONDENSER_BRIEF: string;
|
|
36
|
-
/**
|
|
37
|
-
* Flatten a list of messages into a single `\n`-joined block of `» role:` lines.
|
|
38
|
-
* Exported so the condenser can reuse it for diagnostics/tests.
|
|
39
|
-
*/
|
|
40
|
-
export declare function flattenTranscript(messages: AgentMessage[]): string;
|
|
41
|
-
/**
|
|
42
|
-
* Build the full summarization prompt for a slice of dropped messages.
|
|
43
|
-
*
|
|
44
|
-
* The result is one string: the scope framing, the flattened transcript wrapped
|
|
45
|
-
* in `<scrollback>`, an optional carried digest wrapped in `<carried-digest>`
|
|
46
|
-
* (the iterative-refresh / branch-archival input), and the section template the
|
|
47
|
-
* model fills in. Pass this as the user turn to the injectable completer; pair it
|
|
48
|
-
* with {@link CONDENSER_BRIEF} as the system prompt.
|
|
49
|
-
*
|
|
50
|
-
* @param messages the dropped prefix to summarize
|
|
51
|
-
* @param scope `"session"` (active checkpoint) or `"branch"` (archive)
|
|
52
|
-
* @param priorDigest an optional earlier digest to refresh/extend, threaded in
|
|
53
|
-
* under `<carried-digest>` so the model merges rather than
|
|
54
|
-
* re-derives. Omit for a first-pass condense.
|
|
55
|
-
*/
|
|
56
|
-
export declare function buildSummaryPrompt(messages: AgentMessage[], scope: CondenseScope, priorDigest?: string): string;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Window-budget — Phase 3 / subsystem 05 unit tests.
|
|
3
|
-
*
|
|
4
|
-
* Pure, network-free coverage of the context-window budgeting subsystem:
|
|
5
|
-
* 1. estimateTokens grows with content.
|
|
6
|
-
* 2. isOverBudget is false under the threshold, true over it.
|
|
7
|
-
* 3. planSlice keeps the recent tail and never splits a toolCall/toolResult
|
|
8
|
-
* pair — even when the ideal cut lands mid tool-group it snaps to a safe
|
|
9
|
-
* boundary.
|
|
10
|
-
* 4. createCondenser (with a scripted, no-network completer) condenses an
|
|
11
|
-
* over-budget transcript to a smaller [summary, ...recent] list, and leaves
|
|
12
|
-
* an under-budget transcript unchanged.
|
|
13
|
-
* 5. condenseScope("branch") produces a branch-flavored digest.
|
|
14
|
-
*
|
|
15
|
-
* No network: the only model call path is exercised through an injected
|
|
16
|
-
* {@link CompleteFn} stub that returns a canned {@link AssistantMessage}.
|
|
17
|
-
*/
|
|
18
|
-
export {};
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* createWorkflowAgentRunner — the live {@link WorkflowAgentRunner} that makes the
|
|
3
|
-
* `workflow` tool's `agent()` global spawn real subagents.
|
|
4
|
-
*
|
|
5
|
-
* The pure {@link "./engine"} engine delegates every `agent(prompt, opts)` call
|
|
6
|
-
* to an injected {@link WorkflowAgentRunner}; this module supplies the production
|
|
7
|
-
* implementation. Each subagent run spins a *fresh, isolated* framework
|
|
8
|
-
* {@link Agent} — the same `facade/bot` Agent the conductor and the `task`
|
|
9
|
-
* delegate-runner drive — bound to the parent's model id and credential
|
|
10
|
-
* resolver, given the `'authoring'` capability deck.
|
|
11
|
-
*
|
|
12
|
-
* Two properties matter:
|
|
13
|
-
*
|
|
14
|
-
* 1. **Recursion guard.** The deck is built via `provisionDeck("authoring", …)`,
|
|
15
|
-
* whose profile EXCLUDES the app-novel cards — including the new `workflow`
|
|
16
|
-
* card (registered all-profile-only in {@link "../capability-deck"}). A
|
|
17
|
-
* workflow subagent therefore cannot itself call `workflow` (nor `task`).
|
|
18
|
-
*
|
|
19
|
-
* 2. **Structured output.** When the script passes `opts.schema`, the runner
|
|
20
|
-
* adds the {@link createStructuredOutputTool} `structured_output` tool to the
|
|
21
|
-
* deck and appends the pi "final action MUST be structured_output" contract
|
|
22
|
-
* to the prompt. Because the framework `AgentToolResult` has no `terminate`
|
|
23
|
-
* flag, the tool does NOT end the loop early — the runner instead runs the
|
|
24
|
-
* subagent to completion, then returns `capture.value` (throwing if the
|
|
25
|
-
* subagent never called it). With no schema it returns the final assistant
|
|
26
|
-
* text (the {@link finalAssistantText} pattern, identical to delegate-runner).
|
|
27
|
-
*
|
|
28
|
-
* Cancellation is forwarded: an already-aborted signal short-circuits and an
|
|
29
|
-
* abort raised mid-run calls `agent.abort()`.
|
|
30
|
-
*
|
|
31
|
-
* The model catalog/matcher is built ONCE at create time (the conductor pattern);
|
|
32
|
-
* each `run()` resolves the per-call `opts.model` (falling back to the runner's
|
|
33
|
-
* default `modelId`) against that single matcher. The `spawn` option is a pure
|
|
34
|
-
* test seam — a unit test drives the runner with an in-memory fake instead of a
|
|
35
|
-
* real network round-trip.
|
|
36
|
-
*/
|
|
37
|
-
import { type AgentMessage } from "../conductor";
|
|
38
|
-
import { type AgentTool } from "../capability-deck";
|
|
39
|
-
import { type AgentEvent } from "indusagi/agent";
|
|
40
|
-
import type { WorkflowAgentRunner } from "./engine";
|
|
41
|
-
/**
|
|
42
|
-
* The minimal subagent surface the runner drives.
|
|
43
|
-
*
|
|
44
|
-
* A real framework {@link Agent} satisfies this structurally; a test passes a
|
|
45
|
-
* lightweight fake via {@link WorkflowAgentRunnerOptions.spawn}. Only the pieces
|
|
46
|
-
* the runner touches are named.
|
|
47
|
-
*/
|
|
48
|
-
export interface WorkflowSubAgent {
|
|
49
|
-
prompt(input: string): Promise<void>;
|
|
50
|
-
abort(): void;
|
|
51
|
-
/**
|
|
52
|
-
* Subscribe to the framework `Agent` event stream; returns an unsubscribe
|
|
53
|
-
* thunk. Optional on the structural fake — when absent the runner simply skips
|
|
54
|
-
* live activity reporting (the run still completes and returns its result).
|
|
55
|
-
*/
|
|
56
|
-
subscribe?(fn: (event: AgentEvent) => void): () => void;
|
|
57
|
-
readonly state: {
|
|
58
|
-
messages: readonly AgentMessage[];
|
|
59
|
-
error?: string;
|
|
60
|
-
usage?: unknown;
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
/** The deck of tools handed to a spawned subagent. */
|
|
64
|
-
export interface WorkflowSpawnContext {
|
|
65
|
-
/** The base tools for this run (the `'authoring'` deck, recursion-guarded). */
|
|
66
|
-
readonly tools: AgentTool[];
|
|
67
|
-
/** The resolved system prompt for this subagent. */
|
|
68
|
-
readonly systemPrompt: string;
|
|
69
|
-
}
|
|
70
|
-
/** Configuration for {@link createWorkflowAgentRunner}. */
|
|
71
|
-
export interface WorkflowAgentRunnerOptions {
|
|
72
|
-
/** The default model id a subagent runs under when the script names none. */
|
|
73
|
-
readonly modelId: string;
|
|
74
|
-
/** The working directory the subagent's deck is scoped to. */
|
|
75
|
-
readonly cwd: string;
|
|
76
|
-
/**
|
|
77
|
-
* Per-call credential resolver, forwarded to the framework `Agent` unchanged.
|
|
78
|
-
* Omitted from the agent options entirely when undefined so the framework
|
|
79
|
-
* env-var lookup still wins.
|
|
80
|
-
*/
|
|
81
|
-
readonly getApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;
|
|
82
|
-
/**
|
|
83
|
-
* The base system prompt prepended to every subagent. A sensible default is
|
|
84
|
-
* used when omitted.
|
|
85
|
-
*/
|
|
86
|
-
readonly system?: string;
|
|
87
|
-
/**
|
|
88
|
-
* Test seam: build the subagent instead of constructing a real framework
|
|
89
|
-
* `Agent`. When omitted the runner uses `new Agent`.
|
|
90
|
-
*/
|
|
91
|
-
readonly spawn?: (prompt: string, context: WorkflowSpawnContext) => WorkflowSubAgent;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Build a live {@link WorkflowAgentRunner} the host wires into the deck context.
|
|
95
|
-
*
|
|
96
|
-
* The model catalog/matcher is built once up front (the conductor pattern); each
|
|
97
|
-
* `run()` resolves `opts.model ?? modelId` against it. A schema request wires the
|
|
98
|
-
* `structured_output` capture tool and the structured contract; a model that does
|
|
99
|
-
* not resolve throws out of `run()` so the engine maps it to an `agent ... failed`
|
|
100
|
-
* log + a `null` branch (the engine's per-branch failure-to-null semantics).
|
|
101
|
-
*
|
|
102
|
-
* @param opts the model id, cwd, credential/system, and optional test seam
|
|
103
|
-
* @returns a runner satisfying the engine's {@link WorkflowAgentRunner} contract
|
|
104
|
-
*/
|
|
105
|
-
export declare function createWorkflowAgentRunner(opts: WorkflowAgentRunnerOptions): WorkflowAgentRunner;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* createWorkflowAgentRunner — focused unit tests driven through the `spawn` seam.
|
|
3
|
-
*
|
|
4
|
-
* No model is resolved and no network is touched: each test passes an in-memory
|
|
5
|
-
* fake subagent via `opts.spawn`, so the test exercises the runner's prompt
|
|
6
|
-
* assembly, structured-output capture, final-text extraction, and abort wiring.
|
|
7
|
-
*/
|
|
8
|
-
export {};
|