@moxxy/sdk 0.14.2 → 0.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mode/collect-stream.d.ts +68 -0
- package/dist/mode/collect-stream.d.ts.map +1 -0
- package/dist/mode/collect-stream.js +181 -0
- package/dist/mode/collect-stream.js.map +1 -0
- package/dist/mode/project-messages.d.ts +84 -0
- package/dist/mode/project-messages.d.ts.map +1 -0
- package/dist/mode/project-messages.js +392 -0
- package/dist/mode/project-messages.js.map +1 -0
- package/dist/mode/single-shot.d.ts +17 -0
- package/dist/mode/single-shot.d.ts.map +1 -0
- package/dist/mode/single-shot.js +53 -0
- package/dist/mode/single-shot.js.map +1 -0
- package/dist/mode/stable-hash.d.ts +7 -0
- package/dist/mode/stable-hash.d.ts.map +1 -0
- package/dist/mode/stable-hash.js +20 -0
- package/dist/mode/stable-hash.js.map +1 -0
- package/dist/mode/stuck-loop.d.ts +39 -0
- package/dist/mode/stuck-loop.d.ts.map +1 -0
- package/dist/mode/stuck-loop.js +51 -0
- package/dist/mode/stuck-loop.js.map +1 -0
- package/dist/mode-helpers.d.ts +15 -175
- package/dist/mode-helpers.d.ts.map +1 -1
- package/dist/mode-helpers.js +14 -666
- package/dist/mode-helpers.js.map +1 -1
- package/package.json +1 -1
- package/src/mode/collect-stream.ts +247 -0
- package/src/mode/project-messages.test.ts +121 -0
- package/src/mode/project-messages.ts +461 -0
- package/src/mode/single-shot.ts +63 -0
- package/src/mode/stable-hash.ts +20 -0
- package/src/mode/stuck-loop.ts +89 -0
- package/src/mode-helpers.ts +32 -850
- package/src/mode.test.ts +20 -0
- package/src/token-accounting.test.ts +90 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ProviderMessage, TokenUsage } from '../provider.js';
|
|
2
|
+
import type { ModeContext } from '../mode.js';
|
|
3
|
+
import type { StopReason } from '../provider-utils.js';
|
|
4
|
+
/**
|
|
5
|
+
* Shared bits used by every loop strategy: a typed tool-use struct and a
|
|
6
|
+
* common stream-collection helper that runs `onBeforeProviderCall` hooks
|
|
7
|
+
* and reduces a provider stream down to `{text, toolUses, stopReason}`.
|
|
8
|
+
*
|
|
9
|
+
* Lives in core (not in each loop package) so a new loop strategy stays
|
|
10
|
+
* consistent — and so behavioral fixes here propagate. Previously
|
|
11
|
+
* loop-plan-execute had its own copy that skipped the hook (audit bug).
|
|
12
|
+
*/
|
|
13
|
+
export interface CollectedToolUse {
|
|
14
|
+
readonly id: string;
|
|
15
|
+
readonly name: string;
|
|
16
|
+
readonly input: unknown;
|
|
17
|
+
}
|
|
18
|
+
export interface StreamResult {
|
|
19
|
+
readonly text: string;
|
|
20
|
+
readonly toolUses: ReadonlyArray<CollectedToolUse>;
|
|
21
|
+
readonly stopReason: StopReason;
|
|
22
|
+
readonly error: {
|
|
23
|
+
readonly message: string;
|
|
24
|
+
readonly retryable: boolean;
|
|
25
|
+
} | null;
|
|
26
|
+
/** Token usage reported by the provider on `message_end`, including cache hits/writes. */
|
|
27
|
+
readonly usage?: TokenUsage;
|
|
28
|
+
/**
|
|
29
|
+
* Reasoning/thinking summary for this provider call, when the model emitted
|
|
30
|
+
* any. The mode emits it as a `reasoning_message` event (so it persists and
|
|
31
|
+
* round-trips). `signature`/`encrypted` carry Anthropic's signed thinking
|
|
32
|
+
* block / redacted blob; `redacted` marks display-suppressed reasoning.
|
|
33
|
+
*/
|
|
34
|
+
readonly reasoning?: {
|
|
35
|
+
readonly text: string;
|
|
36
|
+
readonly signature?: string;
|
|
37
|
+
readonly redacted?: boolean;
|
|
38
|
+
readonly encrypted?: string;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Pulls a provider stream, emits `assistant_chunk` events for text deltas,
|
|
43
|
+
* collects tool_use blocks, and returns the final `{text, toolUses, stopReason}`.
|
|
44
|
+
* Runs `onBeforeProviderCall` lifecycle hooks before the call.
|
|
45
|
+
*/
|
|
46
|
+
export declare function collectProviderStream(ctx: ModeContext, messages: ReadonlyArray<ProviderMessage>, opts?: {
|
|
47
|
+
iteration?: number;
|
|
48
|
+
includeTools?: boolean;
|
|
49
|
+
maxTokens?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Index (into `messages`) of the last stable-prefix message, from
|
|
52
|
+
* {@link projectMessages}. Passed to the active cache strategy as
|
|
53
|
+
* `stablePrefixMessageIndex` so it can place a long-lived cross-turn
|
|
54
|
+
* breakpoint at the elision boundary. Omit (or -1) when unknown — the
|
|
55
|
+
* strategy then falls back to its tools/system/tail breakpoints only.
|
|
56
|
+
*/
|
|
57
|
+
stablePrefixIndex?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Number of trailing messages in `messages` that are volatile — injected
|
|
60
|
+
* for this call only (e.g. goal mode's `trailingUserText` nudge) and
|
|
61
|
+
* absent from the append-only log, so they won't recur at the same
|
|
62
|
+
* position next call. Forwarded to the cache strategy as
|
|
63
|
+
* `volatileTailMessageCount` so it keeps its rolling tail breakpoint
|
|
64
|
+
* before them instead of paying a guaranteed-wasted cache write.
|
|
65
|
+
*/
|
|
66
|
+
volatileTailCount?: number;
|
|
67
|
+
}): Promise<StreamResult>;
|
|
68
|
+
//# sourceMappingURL=collect-stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect-stream.d.ts","sourceRoot":"","sources":["../../src/mode/collect-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,eAAe,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGvD;;;;;;;;GAQG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IACnD,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjF,0FAA0F;IAC1F,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE;QACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;KAC7B,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,aAAa,CAAC,eAAe,CAAC,EACxC,IAAI,GAAE;IACJ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACvB,GACL,OAAO,CAAC,YAAY,CAAC,CA8KvB"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { applyLazyTools } from '../tool-gating.js';
|
|
2
|
+
/**
|
|
3
|
+
* Pulls a provider stream, emits `assistant_chunk` events for text deltas,
|
|
4
|
+
* collects tool_use blocks, and returns the final `{text, toolUses, stopReason}`.
|
|
5
|
+
* Runs `onBeforeProviderCall` lifecycle hooks before the call.
|
|
6
|
+
*/
|
|
7
|
+
export async function collectProviderStream(ctx, messages, opts = {}) {
|
|
8
|
+
// Lazy tool gating (opt-in): send only always-on + loaded tool schemas, and
|
|
9
|
+
// index the rest in the system prompt. Runs BEFORE cache planning since it
|
|
10
|
+
// rewrites the system message and the tool list.
|
|
11
|
+
let effectiveMessages = messages;
|
|
12
|
+
let toolList = opts.includeTools === false ? undefined : ctx.tools.list();
|
|
13
|
+
if (ctx.lazyTools && toolList) {
|
|
14
|
+
const gated = applyLazyTools(messages, toolList, ctx.log);
|
|
15
|
+
effectiveMessages = gated.messages;
|
|
16
|
+
toolList = gated.tools;
|
|
17
|
+
}
|
|
18
|
+
// Ask the active cache strategy where to place prompt-cache breakpoints.
|
|
19
|
+
// The strategy is provider-neutral (returns CacheHints); the provider
|
|
20
|
+
// translates them (Anthropic → cache_control). Falls back to no hints when
|
|
21
|
+
// no strategy is registered. The onBeforeProviderCall hook can still adjust.
|
|
22
|
+
const descriptor = ctx.provider.models.find((m) => m.id === ctx.model);
|
|
23
|
+
const cacheHints = ctx.cacheStrategy
|
|
24
|
+
? ctx.cacheStrategy.plan(effectiveMessages, {
|
|
25
|
+
model: ctx.model,
|
|
26
|
+
contextWindow: descriptor?.contextWindow ?? 0,
|
|
27
|
+
log: ctx.log,
|
|
28
|
+
...(opts.stablePrefixIndex != null && opts.stablePrefixIndex >= 0
|
|
29
|
+
? { stablePrefixMessageIndex: opts.stablePrefixIndex }
|
|
30
|
+
: {}),
|
|
31
|
+
...(opts.volatileTailCount != null && opts.volatileTailCount > 0
|
|
32
|
+
? { volatileTailMessageCount: opts.volatileTailCount }
|
|
33
|
+
: {}),
|
|
34
|
+
})
|
|
35
|
+
: undefined;
|
|
36
|
+
// NOTE: `system` is deliberately NOT prefilled with ctx.systemPrompt — the
|
|
37
|
+
// composed system prompt already rides as the leading system-role message
|
|
38
|
+
// (see projectMessages), and providers deliver `req.system` IN ADDITION to
|
|
39
|
+
// message-derived system text. Prefilling it would duplicate the prompt.
|
|
40
|
+
// It stays as the side channel `onBeforeProviderCall` hooks use to inject
|
|
41
|
+
// per-request system text (e.g. the memory consolidation nudge).
|
|
42
|
+
// Forward the per-provider reasoning preference, but only when THIS model
|
|
43
|
+
// advertises `supportsReasoning` — providers ignore the knob otherwise, but
|
|
44
|
+
// gating here keeps requests clean and avoids unsupported-param errors.
|
|
45
|
+
const reqReasoning = descriptor?.supportsReasoning ? ctx.reasoning : undefined;
|
|
46
|
+
const req = {
|
|
47
|
+
model: ctx.model,
|
|
48
|
+
messages: effectiveMessages,
|
|
49
|
+
...(toolList ? { tools: toolList } : {}),
|
|
50
|
+
...(cacheHints && cacheHints.length > 0 ? { cacheHints } : {}),
|
|
51
|
+
...(opts.maxTokens !== undefined ? { maxTokens: opts.maxTokens } : {}),
|
|
52
|
+
...(reqReasoning ? { reasoning: reqReasoning } : {}),
|
|
53
|
+
signal: ctx.signal,
|
|
54
|
+
};
|
|
55
|
+
const transformed = await ctx.hooks.dispatchBeforeProviderCall(req, {
|
|
56
|
+
sessionId: ctx.sessionId,
|
|
57
|
+
cwd: '',
|
|
58
|
+
log: ctx.log,
|
|
59
|
+
env: {},
|
|
60
|
+
turnId: ctx.turnId,
|
|
61
|
+
iteration: opts.iteration ?? 0,
|
|
62
|
+
});
|
|
63
|
+
let text = '';
|
|
64
|
+
const toolUses = new Map();
|
|
65
|
+
let stopReason = 'end_turn';
|
|
66
|
+
let error = null;
|
|
67
|
+
let usage;
|
|
68
|
+
// Reasoning/thinking accumulation for this single provider call. Emitted as a
|
|
69
|
+
// finalized `reasoning_message` by the mode (turn-iterator / goal-loop) so it
|
|
70
|
+
// persists and round-trips; `signature`/`encrypted` carry Anthropic's signed
|
|
71
|
+
// thinking block / redacted blob for replay.
|
|
72
|
+
let reasoningText = '';
|
|
73
|
+
let reasoningSignature;
|
|
74
|
+
let reasoningRedacted = false;
|
|
75
|
+
let reasoningEncrypted;
|
|
76
|
+
let stream;
|
|
77
|
+
try {
|
|
78
|
+
stream = ctx.provider.stream(transformed);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
return {
|
|
82
|
+
text: '',
|
|
83
|
+
toolUses: [],
|
|
84
|
+
stopReason: 'error',
|
|
85
|
+
error: { message: err instanceof Error ? err.message : String(err), retryable: false },
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
for await (const event of stream) {
|
|
90
|
+
switch (event.type) {
|
|
91
|
+
case 'text_delta': {
|
|
92
|
+
text += event.delta;
|
|
93
|
+
await ctx.emit({
|
|
94
|
+
type: 'assistant_chunk',
|
|
95
|
+
sessionId: ctx.sessionId,
|
|
96
|
+
turnId: ctx.turnId,
|
|
97
|
+
source: 'model',
|
|
98
|
+
delta: event.delta,
|
|
99
|
+
});
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
case 'tool_use_start': {
|
|
103
|
+
toolUses.set(event.id, { name: event.name });
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
case 'tool_use_end': {
|
|
107
|
+
const existing = toolUses.get(event.id) ?? {};
|
|
108
|
+
toolUses.set(event.id, { ...existing, input: event.input });
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
case 'message_end': {
|
|
112
|
+
stopReason = event.stopReason;
|
|
113
|
+
if (event.usage)
|
|
114
|
+
usage = event.usage;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case 'error': {
|
|
118
|
+
error = { message: event.message, retryable: event.retryable };
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
case 'reasoning_delta': {
|
|
122
|
+
reasoningText += event.delta;
|
|
123
|
+
// Live preview only — parallels `assistant_chunk`; renderers
|
|
124
|
+
// accumulate ephemerally and clear on the finalized reasoning_message.
|
|
125
|
+
await ctx.emit({
|
|
126
|
+
type: 'reasoning_chunk',
|
|
127
|
+
sessionId: ctx.sessionId,
|
|
128
|
+
turnId: ctx.turnId,
|
|
129
|
+
source: 'model',
|
|
130
|
+
delta: event.delta,
|
|
131
|
+
});
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case 'reasoning_signature': {
|
|
135
|
+
if (event.signature)
|
|
136
|
+
reasoningSignature = event.signature;
|
|
137
|
+
if (event.encrypted)
|
|
138
|
+
reasoningEncrypted = event.encrypted;
|
|
139
|
+
if (event.redacted)
|
|
140
|
+
reasoningRedacted = true;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case 'message_start':
|
|
144
|
+
case 'tool_use_delta':
|
|
145
|
+
default:
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
error = {
|
|
152
|
+
message: err instanceof Error ? err.message : String(err),
|
|
153
|
+
retryable: false,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const finalToolUses = [];
|
|
157
|
+
for (const [id, partial] of toolUses) {
|
|
158
|
+
if (!partial.name)
|
|
159
|
+
continue;
|
|
160
|
+
finalToolUses.push({ id, name: partial.name, input: partial.input ?? {} });
|
|
161
|
+
}
|
|
162
|
+
// Surface reasoning when there's visible text OR an opaque blob to replay
|
|
163
|
+
// (a redacted_thinking block has no text but must still round-trip).
|
|
164
|
+
const reasoning = reasoningText.trim().length > 0 || reasoningEncrypted
|
|
165
|
+
? {
|
|
166
|
+
text: reasoningText,
|
|
167
|
+
...(reasoningSignature ? { signature: reasoningSignature } : {}),
|
|
168
|
+
...(reasoningRedacted ? { redacted: true } : {}),
|
|
169
|
+
...(reasoningEncrypted ? { encrypted: reasoningEncrypted } : {}),
|
|
170
|
+
}
|
|
171
|
+
: undefined;
|
|
172
|
+
return {
|
|
173
|
+
text,
|
|
174
|
+
toolUses: finalToolUses,
|
|
175
|
+
stopReason,
|
|
176
|
+
error,
|
|
177
|
+
...(usage ? { usage } : {}),
|
|
178
|
+
...(reasoning ? { reasoning } : {}),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=collect-stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect-stream.js","sourceRoot":"","sources":["../../src/mode/collect-stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { ContentBlock, ProviderMessage } from '../provider.js';
|
|
2
|
+
import type { ModeContext } from '../mode.js';
|
|
3
|
+
import type { Skill } from '../skill.js';
|
|
4
|
+
import type { MoxxyEvent, UserPromptEvent } from '../events.js';
|
|
5
|
+
import { type ElisionState } from '../elision-state.js';
|
|
6
|
+
/** Appended to the system prompt while elision is active (see projection). */
|
|
7
|
+
export declare const ELISION_SYSTEM_NOTE: string;
|
|
8
|
+
/**
|
|
9
|
+
* Compose a model-facing system prompt that includes any base prompt
|
|
10
|
+
* plus a COMPACT skill index (name + description + triggers only).
|
|
11
|
+
*
|
|
12
|
+
* Lazy-loading design: the body is intentionally NOT inlined. The model
|
|
13
|
+
* matches user intent against the description/triggers, then calls the
|
|
14
|
+
* `load_skill` tool to fetch the body of the skill it picked. This keeps
|
|
15
|
+
* the system prompt small even with many skills installed and avoids
|
|
16
|
+
* paying for skill bodies the model never actually follows.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildSystemPromptWithSkills(baseSystemPrompt: string | undefined, skills: ReadonlyArray<Skill>): string | undefined;
|
|
19
|
+
export interface ProjectMessagesOptions {
|
|
20
|
+
/** Optional system prompt; emitted as the first message when set. */
|
|
21
|
+
readonly systemPrompt?: string;
|
|
22
|
+
/** Optional trailing user message — useful for plan-execute's "Focus on this step now: X". */
|
|
23
|
+
readonly trailingUserText?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Pure projection of a single `user_prompt` event to its content blocks.
|
|
27
|
+
*
|
|
28
|
+
* Extracted from {@link projectMessages} as an independently testable sub-step
|
|
29
|
+
* (u123-5). Returns either the collapsed stub (when the event is an elided
|
|
30
|
+
* conversational turn) or the full text + attachment-expanded blocks — exactly
|
|
31
|
+
* what the inline switch arm produced. Caller decides how to wrap it as a
|
|
32
|
+
* message / record the stable prefix.
|
|
33
|
+
*/
|
|
34
|
+
export declare function projectUserPrompt(event: UserPromptEvent, el: ElisionState): ContentBlock[];
|
|
35
|
+
/**
|
|
36
|
+
* Precompute the set of callIds that have a matching tool_result (or
|
|
37
|
+
* tool_call_denied) somewhere in the log. Used to synthesize a fallback
|
|
38
|
+
* `[interrupted]` tool_result for orphan tool_use blocks when the assistant
|
|
39
|
+
* message gets flushed.
|
|
40
|
+
*
|
|
41
|
+
* Without this fallback the provider rejects the whole conversation with
|
|
42
|
+
* "assistant message with 'tool_calls' must be followed by tool messages
|
|
43
|
+
* responding to each 'tool_call_id'". Orphans typically appear after a
|
|
44
|
+
* cancelled turn, an aborted process, or a tool exception that bypassed the
|
|
45
|
+
* loop's tool_result emit path.
|
|
46
|
+
*
|
|
47
|
+
* Extracted as a pure precompute (u123-5); returns a fresh mutable Set the
|
|
48
|
+
* projection augments as it synthesizes orphan results (so a repeated orphan
|
|
49
|
+
* across groups is only emitted once).
|
|
50
|
+
*/
|
|
51
|
+
export declare function resolvedCallIdSet(events: ReadonlyArray<MoxxyEvent>): Set<string>;
|
|
52
|
+
/**
|
|
53
|
+
* Project the session's event log to a flat list of ProviderMessages
|
|
54
|
+
* suitable for handing to `provider.stream`. Used by every loop strategy.
|
|
55
|
+
*
|
|
56
|
+
* Handles user_prompt, assistant_message, tool_call_requested (grouped
|
|
57
|
+
* into a single assistant message of tool_use blocks), and tool_result.
|
|
58
|
+
* Other event types are passed through as a no-op.
|
|
59
|
+
*
|
|
60
|
+
* This is THE projection every loop strategy uses; it honors compaction
|
|
61
|
+
* events, turn-boundary elision, and the orphan-tool_use fallback. It lives in
|
|
62
|
+
* the SDK so loop plugins stay independent of core.
|
|
63
|
+
*/
|
|
64
|
+
export interface ProjectedMessages {
|
|
65
|
+
readonly messages: ProviderMessage[];
|
|
66
|
+
/**
|
|
67
|
+
* Index (into `messages`) of the last message belonging to the stable,
|
|
68
|
+
* byte-identical prefix — i.e. produced entirely from events at or below the
|
|
69
|
+
* elision high-water mark (which only advances on whole-turn boundaries, so
|
|
70
|
+
* the cut never splits a message). -1 when no elision is active. The
|
|
71
|
+
* `stable-prefix` cache strategy places its long-lived cross-turn breakpoint
|
|
72
|
+
* here; see {@link collectProviderStream}'s `stablePrefixIndex` option.
|
|
73
|
+
*/
|
|
74
|
+
readonly stablePrefixIndex: number;
|
|
75
|
+
}
|
|
76
|
+
export declare function projectMessagesFromLog(ctx: Pick<ModeContext, 'log'>, opts?: ProjectMessagesOptions): ProviderMessage[];
|
|
77
|
+
/**
|
|
78
|
+
* Same projection as {@link projectMessagesFromLog} but also reports the
|
|
79
|
+
* stable-prefix boundary so the active cache strategy can place a cross-turn
|
|
80
|
+
* breakpoint. Modes that build messages this way should thread the returned
|
|
81
|
+
* `stablePrefixIndex` into {@link collectProviderStream}.
|
|
82
|
+
*/
|
|
83
|
+
export declare function projectMessages(ctx: Pick<ModeContext, 'log'>, opts?: ProjectMessagesOptions): ProjectedMessages;
|
|
84
|
+
//# sourceMappingURL=project-messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-messages.d.ts","sourceRoot":"","sources":["../../src/mode/project-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAmB,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAOL,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAG7B,8EAA8E;AAC9E,eAAO,MAAM,mBAAmB,QAKb,CAAC;AAEpB;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CACzC,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,GAC3B,MAAM,GAAG,SAAS,CAoBpB;AAED,MAAM,WAAW,sBAAsB;IACrC,qEAAqE;IACrE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,8FAA8F;IAC9F,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAsFD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE,EAAE,YAAY,GAAG,YAAY,EAAE,CA8B1F;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAQhF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAC;IACrC;;;;;;;OAOG;IACH,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC;AAED,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAC7B,IAAI,GAAE,sBAA2B,GAChC,eAAe,EAAE,CAEnB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAC7B,IAAI,GAAE,sBAA2B,GAChC,iBAAiB,CA2MnB"}
|