@aexol/spectral 0.9.229 → 0.9.231
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 +2 -0
- package/dist/auth-helper.d.ts.map +1 -1
- package/dist/auth-helper.js +14 -8
- package/dist/commands/login.d.ts +12 -4
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +36 -15
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +3 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -1
- package/dist/designer/data/skills/blog-post.d.ts +3 -0
- package/dist/designer/data/skills/blog-post.d.ts.map +1 -0
- package/dist/designer/data/skills/blog-post.js +84 -0
- package/dist/designer/data/skills/blog-post.ts +87 -0
- package/dist/designer/data/skills/critique.d.ts +3 -0
- package/dist/designer/data/skills/critique.d.ts.map +1 -0
- package/dist/designer/data/skills/critique.js +109 -0
- package/dist/designer/data/skills/critique.ts +112 -0
- package/dist/designer/data/skills/dashboard.d.ts +3 -0
- package/dist/designer/data/skills/dashboard.d.ts.map +1 -0
- package/dist/designer/data/skills/dashboard.js +165 -0
- package/dist/designer/data/skills/dashboard.ts +168 -0
- package/dist/designer/data/skills/design-brief.d.ts +3 -0
- package/dist/designer/data/skills/design-brief.d.ts.map +1 -0
- package/dist/designer/data/skills/design-brief.js +141 -0
- package/dist/designer/data/skills/design-brief.ts +144 -0
- package/dist/designer/data/skills/design-skill.d.ts +10 -0
- package/dist/designer/data/skills/design-skill.d.ts.map +1 -0
- package/dist/designer/data/skills/design-skill.js +1 -0
- package/dist/designer/data/skills/design-skill.ts +9 -0
- package/dist/designer/data/skills/docs-page.d.ts +3 -0
- package/dist/designer/data/skills/docs-page.d.ts.map +1 -0
- package/dist/designer/data/skills/docs-page.js +68 -0
- package/dist/designer/data/skills/docs-page.ts +71 -0
- package/dist/designer/data/skills/index.d.ts +3 -0
- package/dist/designer/data/skills/index.d.ts.map +1 -0
- package/dist/designer/data/skills/index.js +28 -0
- package/dist/designer/data/skills/index.ts +30 -0
- package/dist/designer/data/skills/magazine-poster.d.ts +3 -0
- package/dist/designer/data/skills/magazine-poster.d.ts.map +1 -0
- package/dist/designer/data/skills/magazine-poster.js +70 -0
- package/dist/designer/data/skills/magazine-poster.ts +73 -0
- package/dist/designer/data/skills/mobile-app.d.ts +3 -0
- package/dist/designer/data/skills/mobile-app.d.ts.map +1 -0
- package/dist/designer/data/skills/mobile-app.js +229 -0
- package/dist/designer/data/skills/mobile-app.ts +232 -0
- package/dist/designer/data/skills/motion-frames.d.ts +3 -0
- package/dist/designer/data/skills/motion-frames.d.ts.map +1 -0
- package/dist/designer/data/skills/motion-frames.js +121 -0
- package/dist/designer/data/skills/motion-frames.ts +124 -0
- package/dist/designer/data/skills/pricing-page.d.ts +3 -0
- package/dist/designer/data/skills/pricing-page.d.ts.map +1 -0
- package/dist/designer/data/skills/pricing-page.js +76 -0
- package/dist/designer/data/skills/pricing-page.ts +79 -0
- package/dist/designer/data/skills/saas-landing.d.ts +3 -0
- package/dist/designer/data/skills/saas-landing.d.ts.map +1 -0
- package/dist/designer/data/skills/saas-landing.js +71 -0
- package/dist/designer/data/skills/saas-landing.ts +74 -0
- package/dist/designer/data/skills/slide-deck.d.ts +3 -0
- package/dist/designer/data/skills/slide-deck.d.ts.map +1 -0
- package/dist/designer/data/skills/slide-deck.js +213 -0
- package/dist/designer/data/skills/slide-deck.ts +216 -0
- package/dist/designer/data/skills/social-carousel.d.ts +3 -0
- package/dist/designer/data/skills/social-carousel.d.ts.map +1 -0
- package/dist/designer/data/skills/social-carousel.js +135 -0
- package/dist/designer/data/skills/social-carousel.ts +138 -0
- package/dist/designer/data/skills/web-prototype.d.ts +3 -0
- package/dist/designer/data/skills/web-prototype.d.ts.map +1 -0
- package/dist/designer/data/skills/web-prototype.js +159 -0
- package/dist/designer/data/skills/web-prototype.ts +162 -0
- package/dist/designer/skills.d.ts +4 -10
- package/dist/designer/skills.d.ts.map +1 -1
- package/dist/designer/skills.js +2 -1643
- package/dist/extensions/wizard/index.js +9 -1
- package/dist/generated/parser/ast/nodes.d.ts +115 -0
- package/dist/generated/parser/ast/nodes.d.ts.map +1 -0
- package/dist/generated/parser/ast/nodes.js +8 -0
- package/dist/generated/parser/lexer/lexer.d.ts +28 -0
- package/dist/generated/parser/lexer/lexer.d.ts.map +1 -0
- package/dist/generated/parser/{lexer.js → lexer/lexer.js} +1 -180
- package/dist/generated/parser/{lexer.d.ts → lexer/tokens.d.ts} +5 -24
- package/dist/generated/parser/lexer/tokens.d.ts.map +1 -0
- package/dist/generated/parser/lexer/tokens.js +187 -0
- package/dist/generated/parser/mod.d.ts +5 -7
- package/dist/generated/parser/mod.d.ts.map +1 -1
- package/dist/generated/parser/mod.js +2 -1
- package/dist/generated/parser/parser/cursor.d.ts +47 -0
- package/dist/generated/parser/parser/cursor.d.ts.map +1 -0
- package/dist/generated/parser/parser/cursor.js +12 -0
- package/dist/generated/parser/parser/definitions.d.ts +16 -0
- package/dist/generated/parser/parser/definitions.d.ts.map +1 -0
- package/dist/generated/parser/parser/definitions.js +353 -0
- package/dist/generated/parser/parser/expressions.d.ts +17 -0
- package/dist/generated/parser/parser/expressions.d.ts.map +1 -0
- package/dist/generated/parser/parser/expressions.js +165 -0
- package/dist/generated/parser/parser.d.ts +18 -133
- package/dist/generated/parser/parser.d.ts.map +1 -1
- package/dist/generated/parser/parser.js +9 -505
- package/dist/generated/parser/tokenizer.d.ts +1 -2
- package/dist/generated/parser/tokenizer.d.ts.map +1 -1
- package/dist/generated/parser/tokenizer.js +2 -1
- package/dist/generated/parser/validator.d.ts +1 -1
- package/dist/generated/parser/validator.d.ts.map +1 -1
- package/dist/generated/zeus/const.d.ts.map +1 -1
- package/dist/generated/zeus/const.js +21 -0
- package/dist/generated/zeus/index.d.ts +98 -0
- package/dist/generated/zeus/index.d.ts.map +1 -1
- package/dist/mcp/glimpse-ui.js +9 -1
- package/dist/relay/dispatcher.d.ts +11 -104
- package/dist/relay/dispatcher.d.ts.map +1 -1
- package/dist/relay/dispatcher.js +10 -1130
- package/dist/relay/registration.d.ts +10 -2
- package/dist/relay/registration.d.ts.map +1 -1
- package/dist/relay/registration.js +32 -3
- package/dist/relay/rest.d.ts +31 -0
- package/dist/relay/rest.d.ts.map +1 -0
- package/dist/relay/rest.js +85 -0
- package/dist/relay/routing.d.ts +109 -0
- package/dist/relay/routing.d.ts.map +1 -0
- package/dist/relay/routing.js +669 -0
- package/dist/relay/wizard-login.d.ts +17 -0
- package/dist/relay/wizard-login.d.ts.map +1 -0
- package/dist/relay/wizard-login.js +419 -0
- package/dist/sdk/agent-core/agent-loop.d.ts +2 -9
- package/dist/sdk/agent-core/agent-loop.d.ts.map +1 -1
- package/dist/sdk/agent-core/agent-loop.js +4 -288
- package/dist/sdk/agent-core/tool-execution.d.ts +33 -0
- package/dist/sdk/agent-core/tool-execution.d.ts.map +1 -0
- package/dist/sdk/agent-core/tool-execution.js +300 -0
- package/dist/sdk/ai/env-api-keys.js +9 -1
- package/dist/sdk/ai/providers/openai/reasoning-replay.d.ts +48 -0
- package/dist/sdk/ai/providers/openai/reasoning-replay.d.ts.map +1 -0
- package/dist/sdk/ai/providers/openai/reasoning-replay.js +209 -0
- package/dist/sdk/ai/providers/openai-completions.d.ts.map +1 -1
- package/dist/sdk/ai/providers/openai-completions.js +1 -203
- package/dist/sdk/coding-agent/core/compaction/compaction.d.ts +6 -118
- package/dist/sdk/coding-agent/core/compaction/compaction.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/compaction/compaction.js +11 -733
- package/dist/sdk/coding-agent/core/compaction/cut-points.d.ts +58 -0
- package/dist/sdk/coding-agent/core/compaction/cut-points.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/compaction/cut-points.js +191 -0
- package/dist/sdk/coding-agent/core/compaction/dedupe.d.ts +28 -0
- package/dist/sdk/coding-agent/core/compaction/dedupe.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/compaction/dedupe.js +156 -0
- package/dist/sdk/coding-agent/core/compaction/summarize.d.ts +21 -0
- package/dist/sdk/coding-agent/core/compaction/summarize.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/compaction/summarize.js +181 -0
- package/dist/sdk/coding-agent/core/compaction/tokens.d.ts +47 -0
- package/dist/sdk/coding-agent/core/compaction/tokens.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/compaction/tokens.js +224 -0
- package/dist/sdk/coding-agent/core/extensions/session-events.d.ts +157 -0
- package/dist/sdk/coding-agent/core/extensions/session-events.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/extensions/session-events.js +13 -0
- package/dist/sdk/coding-agent/core/extensions/types.d.ts +6 -365
- package/dist/sdk/coding-agent/core/extensions/types.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/extensions/types.js +2 -10
- package/dist/sdk/coding-agent/core/extensions/ui-types.d.ts +219 -0
- package/dist/sdk/coding-agent/core/extensions/ui-types.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/extensions/ui-types.js +4 -0
- package/dist/sdk/coding-agent/core/package/default-package-manager.d.ts +115 -0
- package/dist/sdk/coding-agent/core/package/default-package-manager.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/default-package-manager.js +1184 -0
- package/dist/sdk/coding-agent/core/package/discovery.d.ts +20 -0
- package/dist/sdk/coding-agent/core/package/discovery.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/discovery.js +283 -0
- package/dist/sdk/coding-agent/core/package/ignore.d.ts +29 -0
- package/dist/sdk/coding-agent/core/package/ignore.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/ignore.js +235 -0
- package/dist/sdk/coding-agent/core/package/types.d.ts +128 -0
- package/dist/sdk/coding-agent/core/package/types.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/types.js +18 -0
- package/dist/sdk/coding-agent/core/package/update-check.d.ts +43 -0
- package/dist/sdk/coding-agent/core/package/update-check.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/update-check.js +253 -0
- package/dist/sdk/coding-agent/core/package-manager.d.ts +2 -188
- package/dist/sdk/coding-agent/core/package-manager.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/package-manager.js +1 -1940
- package/dist/sdk/coding-agent/core/session/migrate.d.ts +18 -0
- package/dist/sdk/coding-agent/core/session/migrate.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/session/migrate.js +78 -0
- package/dist/sdk/coding-agent/core/session/types.d.ts +165 -0
- package/dist/sdk/coding-agent/core/session/types.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/session/types.js +4 -0
- package/dist/sdk/coding-agent/core/session-manager.d.ts +3 -161
- package/dist/sdk/coding-agent/core/session-manager.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/session-manager.js +4 -72
- package/package.json +2 -2
- package/dist/generated/parser/lexer.d.ts.map +0 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ChatCompletionAssistantMessageParam } from "openai/resources/chat/completions.js";
|
|
2
|
+
import type { Model, ThinkingContent } from "../../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Reasoning sidecars and replay metadata helpers for OpenAI-compatible
|
|
5
|
+
* providers. Handles extracting reasoning deltas/signatures/metadata from
|
|
6
|
+
* provider payloads, safe reasoning replay fields, Responses-style reasoning
|
|
7
|
+
* sidecar messages, and inline <think> tag splitting.
|
|
8
|
+
*/
|
|
9
|
+
export declare const SAFE_REASONING_REPLAY_FIELDS: readonly ["reasoning_content", "reasoning", "reasoning_text", "reasoning_summary", "reasoning_summary_text", "summary_text", "summary"];
|
|
10
|
+
export type SafeReasoningReplayField = (typeof SAFE_REASONING_REPLAY_FIELDS)[number];
|
|
11
|
+
export interface ResponsesReasoningSidecar {
|
|
12
|
+
id?: string;
|
|
13
|
+
item_id?: string;
|
|
14
|
+
output_index?: number;
|
|
15
|
+
summary_index?: number;
|
|
16
|
+
encrypted_content?: string;
|
|
17
|
+
}
|
|
18
|
+
export type ChatCompletionAssistantMessageWithReasoningSidecars = ChatCompletionAssistantMessageParam & Partial<Record<SafeReasoningReplayField, string>> & {
|
|
19
|
+
reasoning_start?: ResponsesReasoningSidecar;
|
|
20
|
+
reasoning_end?: ResponsesReasoningSidecar;
|
|
21
|
+
};
|
|
22
|
+
export declare function asRecord(value: unknown): Record<string, unknown> | undefined;
|
|
23
|
+
export declare function collectReasoningText(value: unknown): string;
|
|
24
|
+
export declare function extractReasoningDelta(deltaFields: Record<string, unknown>): {
|
|
25
|
+
field: string;
|
|
26
|
+
delta: string;
|
|
27
|
+
} | undefined;
|
|
28
|
+
export declare function extractReasoningSignature(value: unknown): string | undefined;
|
|
29
|
+
export declare function extractReasoningMetadata(value: unknown): Record<string, unknown> | undefined;
|
|
30
|
+
export declare function stringMetadata(metadata: Record<string, unknown> | undefined, key: string): string | undefined;
|
|
31
|
+
export declare function numberMetadata(metadata: Record<string, unknown> | undefined, key: string): number | undefined;
|
|
32
|
+
export declare function hasEncryptedReasoningMetadata(block: ThinkingContent): boolean;
|
|
33
|
+
export declare function buildResponsesReasoningSidecar(metadata: Record<string, unknown> | undefined, includeOutputIndex: boolean): ResponsesReasoningSidecar;
|
|
34
|
+
export declare function isSafeReasoningReplayField(field: string): field is SafeReasoningReplayField;
|
|
35
|
+
export declare function normalizeReasoningReplayField(field: string | undefined, model: Model<"openai-completions">): SafeReasoningReplayField;
|
|
36
|
+
export declare function setAssistantReasoningField(message: ChatCompletionAssistantMessageParam, field: SafeReasoningReplayField, value: string): void;
|
|
37
|
+
export declare function setAssistantReasoningLifecycleSidecars(message: ChatCompletionAssistantMessageParam, blocks: ThinkingContent[]): void;
|
|
38
|
+
export declare function assistantHasReasoningReplay(message: ChatCompletionAssistantMessageParam): boolean;
|
|
39
|
+
export declare function mergeThinkingMetadata(block: ThinkingContent, metadata?: Record<string, unknown>): void;
|
|
40
|
+
export declare function splitInlineThinkingDelta(pending: string, inInlineThinking: boolean, delta: string): {
|
|
41
|
+
parts: Array<{
|
|
42
|
+
type: "text" | "thinking";
|
|
43
|
+
delta: string;
|
|
44
|
+
}>;
|
|
45
|
+
pending: string;
|
|
46
|
+
inInlineThinking: boolean;
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=reasoning-replay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reasoning-replay.d.ts","sourceRoot":"","sources":["../../../../../src/sdk/ai/providers/openai/reasoning-replay.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reasoning sidecars and replay metadata helpers for OpenAI-compatible
|
|
3
|
+
* providers. Handles extracting reasoning deltas/signatures/metadata from
|
|
4
|
+
* provider payloads, safe reasoning replay fields, Responses-style reasoning
|
|
5
|
+
* sidecar messages, and inline <think> tag splitting.
|
|
6
|
+
*/
|
|
7
|
+
export const SAFE_REASONING_REPLAY_FIELDS = [
|
|
8
|
+
"reasoning_content",
|
|
9
|
+
"reasoning",
|
|
10
|
+
"reasoning_text",
|
|
11
|
+
"reasoning_summary",
|
|
12
|
+
"reasoning_summary_text",
|
|
13
|
+
"summary_text",
|
|
14
|
+
"summary",
|
|
15
|
+
];
|
|
16
|
+
export function asRecord(value) {
|
|
17
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
18
|
+
? value
|
|
19
|
+
: undefined;
|
|
20
|
+
}
|
|
21
|
+
export function collectReasoningText(value) {
|
|
22
|
+
if (typeof value === "string")
|
|
23
|
+
return value;
|
|
24
|
+
if (Array.isArray(value))
|
|
25
|
+
return value.map(collectReasoningText).join("");
|
|
26
|
+
const record = asRecord(value);
|
|
27
|
+
if (!record)
|
|
28
|
+
return "";
|
|
29
|
+
const direct = [
|
|
30
|
+
record.delta,
|
|
31
|
+
record.text,
|
|
32
|
+
record.value,
|
|
33
|
+
record.output_text,
|
|
34
|
+
record.reasoning_text,
|
|
35
|
+
record.reasoning_content,
|
|
36
|
+
record.reasoning_summary,
|
|
37
|
+
record.reasoning_summary_text,
|
|
38
|
+
record.summary_text,
|
|
39
|
+
];
|
|
40
|
+
for (const candidate of direct) {
|
|
41
|
+
if (typeof candidate === "string" && candidate.length > 0)
|
|
42
|
+
return candidate;
|
|
43
|
+
}
|
|
44
|
+
return [record.summary, record.parts, record.content, record.annotations]
|
|
45
|
+
.map(collectReasoningText)
|
|
46
|
+
.join("");
|
|
47
|
+
}
|
|
48
|
+
export function extractReasoningDelta(deltaFields) {
|
|
49
|
+
const reasoningFields = [
|
|
50
|
+
"reasoning_content",
|
|
51
|
+
"reasoning",
|
|
52
|
+
"reasoning_text",
|
|
53
|
+
"reasoning_summary",
|
|
54
|
+
"reasoning_summary_text",
|
|
55
|
+
"summary_text",
|
|
56
|
+
"summary",
|
|
57
|
+
];
|
|
58
|
+
for (const field of reasoningFields) {
|
|
59
|
+
const delta = collectReasoningText(deltaFields[field]);
|
|
60
|
+
if (delta.length > 0)
|
|
61
|
+
return { field, delta };
|
|
62
|
+
}
|
|
63
|
+
const details = collectReasoningText(deltaFields.reasoning_details);
|
|
64
|
+
return details.length > 0
|
|
65
|
+
? { field: "reasoning_details", delta: details }
|
|
66
|
+
: undefined;
|
|
67
|
+
}
|
|
68
|
+
export function extractReasoningSignature(value) {
|
|
69
|
+
if (typeof value === "string" && value.length > 0)
|
|
70
|
+
return value;
|
|
71
|
+
const record = asRecord(value);
|
|
72
|
+
if (!record)
|
|
73
|
+
return undefined;
|
|
74
|
+
for (const candidate of [
|
|
75
|
+
record.id,
|
|
76
|
+
record.item_id,
|
|
77
|
+
record.data,
|
|
78
|
+
]) {
|
|
79
|
+
if (typeof candidate === "string" && candidate.length > 0)
|
|
80
|
+
return candidate;
|
|
81
|
+
}
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
export function extractReasoningMetadata(value) {
|
|
85
|
+
const record = asRecord(value);
|
|
86
|
+
if (!record)
|
|
87
|
+
return undefined;
|
|
88
|
+
const metadata = {};
|
|
89
|
+
for (const key of [
|
|
90
|
+
"id",
|
|
91
|
+
"item_id",
|
|
92
|
+
"output_index",
|
|
93
|
+
"summary_index",
|
|
94
|
+
"encrypted_content",
|
|
95
|
+
"type",
|
|
96
|
+
]) {
|
|
97
|
+
if (record[key] !== undefined && record[key] !== null)
|
|
98
|
+
metadata[key] = record[key];
|
|
99
|
+
}
|
|
100
|
+
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
101
|
+
}
|
|
102
|
+
export function stringMetadata(metadata, key) {
|
|
103
|
+
const value = metadata?.[key];
|
|
104
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
105
|
+
}
|
|
106
|
+
export function numberMetadata(metadata, key) {
|
|
107
|
+
const value = metadata?.[key];
|
|
108
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
109
|
+
}
|
|
110
|
+
export function hasEncryptedReasoningMetadata(block) {
|
|
111
|
+
return stringMetadata(block.thinkingMetadata, "encrypted_content") !== undefined;
|
|
112
|
+
}
|
|
113
|
+
export function buildResponsesReasoningSidecar(metadata, includeOutputIndex) {
|
|
114
|
+
const sidecar = {};
|
|
115
|
+
const id = stringMetadata(metadata, "id");
|
|
116
|
+
if (id)
|
|
117
|
+
sidecar.id = id;
|
|
118
|
+
const itemId = stringMetadata(metadata, "item_id");
|
|
119
|
+
if (itemId)
|
|
120
|
+
sidecar.item_id = itemId;
|
|
121
|
+
if (includeOutputIndex) {
|
|
122
|
+
const outputIndex = numberMetadata(metadata, "output_index");
|
|
123
|
+
if (outputIndex !== undefined)
|
|
124
|
+
sidecar.output_index = outputIndex;
|
|
125
|
+
const summaryIndex = numberMetadata(metadata, "summary_index");
|
|
126
|
+
if (summaryIndex !== undefined)
|
|
127
|
+
sidecar.summary_index = summaryIndex;
|
|
128
|
+
}
|
|
129
|
+
const encryptedContent = stringMetadata(metadata, "encrypted_content");
|
|
130
|
+
if (encryptedContent)
|
|
131
|
+
sidecar.encrypted_content = encryptedContent;
|
|
132
|
+
return sidecar;
|
|
133
|
+
}
|
|
134
|
+
export function isSafeReasoningReplayField(field) {
|
|
135
|
+
return SAFE_REASONING_REPLAY_FIELDS.includes(field);
|
|
136
|
+
}
|
|
137
|
+
export function normalizeReasoningReplayField(field, model) {
|
|
138
|
+
const normalized = model.provider === "opencode-go" && field === "reasoning"
|
|
139
|
+
? "reasoning_content"
|
|
140
|
+
: field;
|
|
141
|
+
return normalized && isSafeReasoningReplayField(normalized)
|
|
142
|
+
? normalized
|
|
143
|
+
: "reasoning_content";
|
|
144
|
+
}
|
|
145
|
+
export function setAssistantReasoningField(message, field, value) {
|
|
146
|
+
const messageWithSidecars = message;
|
|
147
|
+
messageWithSidecars[field] = value;
|
|
148
|
+
}
|
|
149
|
+
export function setAssistantReasoningLifecycleSidecars(message, blocks) {
|
|
150
|
+
const encryptedBlock = blocks.find(hasEncryptedReasoningMetadata);
|
|
151
|
+
if (!encryptedBlock)
|
|
152
|
+
return;
|
|
153
|
+
const messageWithSidecars = message;
|
|
154
|
+
messageWithSidecars.reasoning_start = buildResponsesReasoningSidecar(encryptedBlock.thinkingMetadata, true);
|
|
155
|
+
messageWithSidecars.reasoning_content = blocks
|
|
156
|
+
.map((block) => block.thinking)
|
|
157
|
+
.join("\n");
|
|
158
|
+
messageWithSidecars.reasoning_end = buildResponsesReasoningSidecar(encryptedBlock.thinkingMetadata, false);
|
|
159
|
+
}
|
|
160
|
+
export function assistantHasReasoningReplay(message) {
|
|
161
|
+
const messageWithSidecars = message;
|
|
162
|
+
return messageWithSidecars.reasoning_start !== undefined ||
|
|
163
|
+
messageWithSidecars.reasoning_end !== undefined ||
|
|
164
|
+
SAFE_REASONING_REPLAY_FIELDS.some((field) => typeof messageWithSidecars[field] === "string");
|
|
165
|
+
}
|
|
166
|
+
export function mergeThinkingMetadata(block, metadata) {
|
|
167
|
+
if (!metadata)
|
|
168
|
+
return;
|
|
169
|
+
block.thinkingMetadata = { ...(block.thinkingMetadata ?? {}), ...metadata };
|
|
170
|
+
}
|
|
171
|
+
export function splitInlineThinkingDelta(pending, inInlineThinking, delta) {
|
|
172
|
+
const parts = [];
|
|
173
|
+
let buffer = pending + delta;
|
|
174
|
+
let thinking = inInlineThinking;
|
|
175
|
+
const append = (type, value) => {
|
|
176
|
+
if (!value)
|
|
177
|
+
return;
|
|
178
|
+
const last = parts[parts.length - 1];
|
|
179
|
+
if (last?.type === type) {
|
|
180
|
+
last.delta += value;
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
parts.push({ type, delta: value });
|
|
184
|
+
};
|
|
185
|
+
while (buffer.length > 0) {
|
|
186
|
+
const tag = thinking ? "</think>" : "<think>";
|
|
187
|
+
const idx = buffer.toLowerCase().indexOf(tag);
|
|
188
|
+
if (idx >= 0) {
|
|
189
|
+
append(thinking ? "thinking" : "text", buffer.slice(0, idx));
|
|
190
|
+
buffer = buffer.slice(idx + tag.length);
|
|
191
|
+
thinking = !thinking;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
const maxTagLength = "</think>".length - 1;
|
|
195
|
+
let keep = 0;
|
|
196
|
+
const limit = Math.min(maxTagLength, buffer.length);
|
|
197
|
+
for (let size = limit; size > 0; size--) {
|
|
198
|
+
const suffix = buffer.slice(-size).toLowerCase();
|
|
199
|
+
if ("<think>".startsWith(suffix) || "</think>".startsWith(suffix)) {
|
|
200
|
+
keep = size;
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
append(thinking ? "thinking" : "text", buffer.slice(0, buffer.length - keep));
|
|
205
|
+
buffer = buffer.slice(buffer.length - keep);
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
return { parts, pending: buffer, inInlineThinking: thinking };
|
|
209
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-completions.d.ts","sourceRoot":"","sources":["../../../../src/sdk/ai/providers/openai-completions.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAMX,0BAA0B,EAE1B,MAAM,sCAAsC,CAAC;AAI9C,OAAO,KAAK,EAGX,OAAO,EAGP,KAAK,EACL,uBAAuB,EACvB,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAMb,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"openai-completions.d.ts","sourceRoot":"","sources":["../../../../src/sdk/ai/providers/openai-completions.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAMX,0BAA0B,EAE1B,MAAM,sCAAsC,CAAC;AAI9C,OAAO,KAAK,EAGX,OAAO,EAGP,KAAK,EACL,uBAAuB,EACvB,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAMb,MAAM,aAAa,CAAC;AA+FrB,MAAM,WAAW,wBAAyB,SAAQ,aAAa;IAC9D,UAAU,CAAC,EACR,MAAM,GACN,MAAM,GACN,UAAU,GACV;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IACpD,eAAe,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;CAClE;AAED,KAAK,+BAA+B,GAAG,QAAQ,CAAC,uBAAuB,CAAC,CAAC;AAuBzE,eAAO,MAAM,uBAAuB,EAAE,cAAc,CACnD,oBAAoB,EACpB,wBAAwB,CAylBxB,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,cAAc,CACzD,oBAAoB,EACpB,mBAAmB,CAyBnB,CAAC;AAkNF,wBAAgB,eAAe,CAC9B,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,EAClC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,+BAA+B,GACrC,0BAA0B,EAAE,CA0R9B"}
|
|
@@ -13,6 +13,7 @@ import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
|
13
13
|
import { clampOpenAIPromptCacheKey } from "./openai-prompt-cache.js";
|
|
14
14
|
import { buildBaseOptions } from "./simple-options.js";
|
|
15
15
|
import { transformMessages } from "./transform-messages.js";
|
|
16
|
+
import { assistantHasReasoningReplay, extractReasoningDelta, extractReasoningMetadata, extractReasoningSignature, hasEncryptedReasoningMetadata, mergeThinkingMetadata, normalizeReasoningReplayField, setAssistantReasoningField, setAssistantReasoningLifecycleSidecars, splitInlineThinkingDelta, } from "./openai/reasoning-replay.js";
|
|
16
17
|
/**
|
|
17
18
|
* Check if conversation messages contain tool calls or tool results.
|
|
18
19
|
* This is needed because Anthropic (via proxy) requires the tools param
|
|
@@ -76,15 +77,6 @@ async function backendImageBaseUrl(explicit) {
|
|
|
76
77
|
function defaultWarn(message) {
|
|
77
78
|
console.warn(`[spectral] ${message}`);
|
|
78
79
|
}
|
|
79
|
-
const SAFE_REASONING_REPLAY_FIELDS = [
|
|
80
|
-
"reasoning_content",
|
|
81
|
-
"reasoning",
|
|
82
|
-
"reasoning_text",
|
|
83
|
-
"reasoning_summary",
|
|
84
|
-
"reasoning_summary_text",
|
|
85
|
-
"summary_text",
|
|
86
|
-
"summary",
|
|
87
|
-
];
|
|
88
80
|
function isOpenRouterModel(model) {
|
|
89
81
|
return model.provider === "openrouter" ||
|
|
90
82
|
model.baseUrl.includes("openrouter.ai");
|
|
@@ -99,200 +91,6 @@ function resolveCacheRetention(cacheRetention) {
|
|
|
99
91
|
}
|
|
100
92
|
return "short";
|
|
101
93
|
}
|
|
102
|
-
function asRecord(value) {
|
|
103
|
-
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
104
|
-
? value
|
|
105
|
-
: undefined;
|
|
106
|
-
}
|
|
107
|
-
function collectReasoningText(value) {
|
|
108
|
-
if (typeof value === "string")
|
|
109
|
-
return value;
|
|
110
|
-
if (Array.isArray(value))
|
|
111
|
-
return value.map(collectReasoningText).join("");
|
|
112
|
-
const record = asRecord(value);
|
|
113
|
-
if (!record)
|
|
114
|
-
return "";
|
|
115
|
-
const direct = [
|
|
116
|
-
record.delta,
|
|
117
|
-
record.text,
|
|
118
|
-
record.value,
|
|
119
|
-
record.output_text,
|
|
120
|
-
record.reasoning_text,
|
|
121
|
-
record.reasoning_content,
|
|
122
|
-
record.reasoning_summary,
|
|
123
|
-
record.reasoning_summary_text,
|
|
124
|
-
record.summary_text,
|
|
125
|
-
];
|
|
126
|
-
for (const candidate of direct) {
|
|
127
|
-
if (typeof candidate === "string" && candidate.length > 0)
|
|
128
|
-
return candidate;
|
|
129
|
-
}
|
|
130
|
-
return [record.summary, record.parts, record.content, record.annotations]
|
|
131
|
-
.map(collectReasoningText)
|
|
132
|
-
.join("");
|
|
133
|
-
}
|
|
134
|
-
function extractReasoningDelta(deltaFields) {
|
|
135
|
-
const reasoningFields = [
|
|
136
|
-
"reasoning_content",
|
|
137
|
-
"reasoning",
|
|
138
|
-
"reasoning_text",
|
|
139
|
-
"reasoning_summary",
|
|
140
|
-
"reasoning_summary_text",
|
|
141
|
-
"summary_text",
|
|
142
|
-
"summary",
|
|
143
|
-
];
|
|
144
|
-
for (const field of reasoningFields) {
|
|
145
|
-
const delta = collectReasoningText(deltaFields[field]);
|
|
146
|
-
if (delta.length > 0)
|
|
147
|
-
return { field, delta };
|
|
148
|
-
}
|
|
149
|
-
const details = collectReasoningText(deltaFields.reasoning_details);
|
|
150
|
-
return details.length > 0
|
|
151
|
-
? { field: "reasoning_details", delta: details }
|
|
152
|
-
: undefined;
|
|
153
|
-
}
|
|
154
|
-
function extractReasoningSignature(value) {
|
|
155
|
-
if (typeof value === "string" && value.length > 0)
|
|
156
|
-
return value;
|
|
157
|
-
const record = asRecord(value);
|
|
158
|
-
if (!record)
|
|
159
|
-
return undefined;
|
|
160
|
-
for (const candidate of [
|
|
161
|
-
record.id,
|
|
162
|
-
record.item_id,
|
|
163
|
-
record.data,
|
|
164
|
-
]) {
|
|
165
|
-
if (typeof candidate === "string" && candidate.length > 0)
|
|
166
|
-
return candidate;
|
|
167
|
-
}
|
|
168
|
-
return undefined;
|
|
169
|
-
}
|
|
170
|
-
function extractReasoningMetadata(value) {
|
|
171
|
-
const record = asRecord(value);
|
|
172
|
-
if (!record)
|
|
173
|
-
return undefined;
|
|
174
|
-
const metadata = {};
|
|
175
|
-
for (const key of [
|
|
176
|
-
"id",
|
|
177
|
-
"item_id",
|
|
178
|
-
"output_index",
|
|
179
|
-
"summary_index",
|
|
180
|
-
"encrypted_content",
|
|
181
|
-
"type",
|
|
182
|
-
]) {
|
|
183
|
-
if (record[key] !== undefined && record[key] !== null)
|
|
184
|
-
metadata[key] = record[key];
|
|
185
|
-
}
|
|
186
|
-
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
187
|
-
}
|
|
188
|
-
function stringMetadata(metadata, key) {
|
|
189
|
-
const value = metadata?.[key];
|
|
190
|
-
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
191
|
-
}
|
|
192
|
-
function numberMetadata(metadata, key) {
|
|
193
|
-
const value = metadata?.[key];
|
|
194
|
-
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
195
|
-
}
|
|
196
|
-
function hasEncryptedReasoningMetadata(block) {
|
|
197
|
-
return stringMetadata(block.thinkingMetadata, "encrypted_content") !== undefined;
|
|
198
|
-
}
|
|
199
|
-
function buildResponsesReasoningSidecar(metadata, includeOutputIndex) {
|
|
200
|
-
const sidecar = {};
|
|
201
|
-
const id = stringMetadata(metadata, "id");
|
|
202
|
-
if (id)
|
|
203
|
-
sidecar.id = id;
|
|
204
|
-
const itemId = stringMetadata(metadata, "item_id");
|
|
205
|
-
if (itemId)
|
|
206
|
-
sidecar.item_id = itemId;
|
|
207
|
-
if (includeOutputIndex) {
|
|
208
|
-
const outputIndex = numberMetadata(metadata, "output_index");
|
|
209
|
-
if (outputIndex !== undefined)
|
|
210
|
-
sidecar.output_index = outputIndex;
|
|
211
|
-
const summaryIndex = numberMetadata(metadata, "summary_index");
|
|
212
|
-
if (summaryIndex !== undefined)
|
|
213
|
-
sidecar.summary_index = summaryIndex;
|
|
214
|
-
}
|
|
215
|
-
const encryptedContent = stringMetadata(metadata, "encrypted_content");
|
|
216
|
-
if (encryptedContent)
|
|
217
|
-
sidecar.encrypted_content = encryptedContent;
|
|
218
|
-
return sidecar;
|
|
219
|
-
}
|
|
220
|
-
function isSafeReasoningReplayField(field) {
|
|
221
|
-
return SAFE_REASONING_REPLAY_FIELDS.includes(field);
|
|
222
|
-
}
|
|
223
|
-
function normalizeReasoningReplayField(field, model) {
|
|
224
|
-
const normalized = model.provider === "opencode-go" && field === "reasoning"
|
|
225
|
-
? "reasoning_content"
|
|
226
|
-
: field;
|
|
227
|
-
return normalized && isSafeReasoningReplayField(normalized)
|
|
228
|
-
? normalized
|
|
229
|
-
: "reasoning_content";
|
|
230
|
-
}
|
|
231
|
-
function setAssistantReasoningField(message, field, value) {
|
|
232
|
-
const messageWithSidecars = message;
|
|
233
|
-
messageWithSidecars[field] = value;
|
|
234
|
-
}
|
|
235
|
-
function setAssistantReasoningLifecycleSidecars(message, blocks) {
|
|
236
|
-
const encryptedBlock = blocks.find(hasEncryptedReasoningMetadata);
|
|
237
|
-
if (!encryptedBlock)
|
|
238
|
-
return;
|
|
239
|
-
const messageWithSidecars = message;
|
|
240
|
-
messageWithSidecars.reasoning_start = buildResponsesReasoningSidecar(encryptedBlock.thinkingMetadata, true);
|
|
241
|
-
messageWithSidecars.reasoning_content = blocks
|
|
242
|
-
.map((block) => block.thinking)
|
|
243
|
-
.join("\n");
|
|
244
|
-
messageWithSidecars.reasoning_end = buildResponsesReasoningSidecar(encryptedBlock.thinkingMetadata, false);
|
|
245
|
-
}
|
|
246
|
-
function assistantHasReasoningReplay(message) {
|
|
247
|
-
const messageWithSidecars = message;
|
|
248
|
-
return messageWithSidecars.reasoning_start !== undefined ||
|
|
249
|
-
messageWithSidecars.reasoning_end !== undefined ||
|
|
250
|
-
SAFE_REASONING_REPLAY_FIELDS.some((field) => typeof messageWithSidecars[field] === "string");
|
|
251
|
-
}
|
|
252
|
-
function mergeThinkingMetadata(block, metadata) {
|
|
253
|
-
if (!metadata)
|
|
254
|
-
return;
|
|
255
|
-
block.thinkingMetadata = { ...(block.thinkingMetadata ?? {}), ...metadata };
|
|
256
|
-
}
|
|
257
|
-
function splitInlineThinkingDelta(pending, inInlineThinking, delta) {
|
|
258
|
-
const parts = [];
|
|
259
|
-
let buffer = pending + delta;
|
|
260
|
-
let thinking = inInlineThinking;
|
|
261
|
-
const append = (type, value) => {
|
|
262
|
-
if (!value)
|
|
263
|
-
return;
|
|
264
|
-
const last = parts[parts.length - 1];
|
|
265
|
-
if (last?.type === type) {
|
|
266
|
-
last.delta += value;
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
parts.push({ type, delta: value });
|
|
270
|
-
};
|
|
271
|
-
while (buffer.length > 0) {
|
|
272
|
-
const tag = thinking ? "</think>" : "<think>";
|
|
273
|
-
const idx = buffer.toLowerCase().indexOf(tag);
|
|
274
|
-
if (idx >= 0) {
|
|
275
|
-
append(thinking ? "thinking" : "text", buffer.slice(0, idx));
|
|
276
|
-
buffer = buffer.slice(idx + tag.length);
|
|
277
|
-
thinking = !thinking;
|
|
278
|
-
continue;
|
|
279
|
-
}
|
|
280
|
-
const maxTagLength = "</think>".length - 1;
|
|
281
|
-
let keep = 0;
|
|
282
|
-
const limit = Math.min(maxTagLength, buffer.length);
|
|
283
|
-
for (let size = limit; size > 0; size--) {
|
|
284
|
-
const suffix = buffer.slice(-size).toLowerCase();
|
|
285
|
-
if ("<think>".startsWith(suffix) || "</think>".startsWith(suffix)) {
|
|
286
|
-
keep = size;
|
|
287
|
-
break;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
append(thinking ? "thinking" : "text", buffer.slice(0, buffer.length - keep));
|
|
291
|
-
buffer = buffer.slice(buffer.length - keep);
|
|
292
|
-
break;
|
|
293
|
-
}
|
|
294
|
-
return { parts, pending: buffer, inInlineThinking: thinking };
|
|
295
|
-
}
|
|
296
94
|
export const streamOpenAICompletions = (model, context, options) => {
|
|
297
95
|
const stream = new AssistantMessageEventStream();
|
|
298
96
|
(async () => {
|
|
@@ -5,21 +5,21 @@
|
|
|
5
5
|
* and after compaction the session is reloaded.
|
|
6
6
|
*/
|
|
7
7
|
import type { AgentMessage, StreamFn, ThinkingLevel } from "../../../agent-core/index.js";
|
|
8
|
-
import type { Model
|
|
8
|
+
import type { Model } from "../../../ai/index.js";
|
|
9
9
|
import { type SessionEntry } from "../session-manager.js";
|
|
10
10
|
import { type FileOperations } from "./utils.js";
|
|
11
11
|
import { type ConversationCompactionPolicy, type ManualCompactionPolicy } from "./policy.js";
|
|
12
|
+
import { type CompactionTokenSourceBucket } from "./tokens.js";
|
|
13
|
+
export { type CompactionTokenSourceBucket, calculateContextTokens, type ContextUsageEstimate, estimateCompactionTokenMetrics, estimateContextTokens, estimateTextTokens, estimateTokens, getLastAssistantUsage, shouldCompact, } from "./tokens.js";
|
|
14
|
+
export { type CutPointResult, type FindCutPointOptions, findCutPoint, findTurnStartIndex, } from "./cut-points.js";
|
|
15
|
+
export { generateSummary } from "./summarize.js";
|
|
16
|
+
export { deduplicateToolCalls } from "./dedupe.js";
|
|
12
17
|
/** Details stored in CompactionEntry.details for file tracking */
|
|
13
18
|
export interface CompactionDetails {
|
|
14
19
|
readFiles: string[];
|
|
15
20
|
modifiedFiles: string[];
|
|
16
21
|
}
|
|
17
22
|
export type CompactionSkipReason = "non_shrinking";
|
|
18
|
-
export interface CompactionTokenSourceBucket {
|
|
19
|
-
type: "role" | "tool" | "source";
|
|
20
|
-
name: string;
|
|
21
|
-
tokens: number;
|
|
22
|
-
}
|
|
23
23
|
/** Result from compact() - SessionManager adds uuid/parentUuid when saving */
|
|
24
24
|
export interface CompactionResult<T = unknown> {
|
|
25
25
|
summary: string;
|
|
@@ -55,95 +55,6 @@ export declare const MANUAL_COMPACTION_KEEP_RECENT_TOKENS: number;
|
|
|
55
55
|
* default session does not keep the whole eligible branch and compact nothing.
|
|
56
56
|
*/
|
|
57
57
|
export declare function getManualCompactionSettings(settings: CompactionSettings, manualPolicy?: ManualCompactionPolicy): CompactionSettings;
|
|
58
|
-
/**
|
|
59
|
-
* Calculate total context tokens from usage.
|
|
60
|
-
* Uses the native totalTokens field when available, falls back to computing from components.
|
|
61
|
-
*/
|
|
62
|
-
export declare function calculateContextTokens(usage: Usage): number;
|
|
63
|
-
/**
|
|
64
|
-
* Find the last non-aborted assistant message usage from session entries.
|
|
65
|
-
*/
|
|
66
|
-
export declare function getLastAssistantUsage(entries: SessionEntry[]): Usage | undefined;
|
|
67
|
-
export interface ContextUsageEstimate {
|
|
68
|
-
tokens: number;
|
|
69
|
-
usageTokens: number;
|
|
70
|
-
trailingTokens: number;
|
|
71
|
-
lastUsageIndex: number | null;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Estimate context tokens from messages, using the last assistant usage when available.
|
|
75
|
-
* If there are messages after the last usage, estimate their tokens with estimateTokens.
|
|
76
|
-
*/
|
|
77
|
-
export declare function estimateContextTokens(messages: AgentMessage[]): ContextUsageEstimate;
|
|
78
|
-
/**
|
|
79
|
-
* Check if compaction should trigger based on context usage.
|
|
80
|
-
*/
|
|
81
|
-
export declare function shouldCompact(contextTokens: number, contextWindow: number, settings: CompactionSettings): boolean;
|
|
82
|
-
/**
|
|
83
|
-
* Estimate token count for a message using chars/4 heuristic.
|
|
84
|
-
* This is conservative (overestimates tokens).
|
|
85
|
-
*/
|
|
86
|
-
export declare function estimateTokens(message: AgentMessage): number;
|
|
87
|
-
/**
|
|
88
|
-
* Find the user message (or bashExecution) that starts the turn containing the given entry index.
|
|
89
|
-
* Returns -1 if no turn start found before the index.
|
|
90
|
-
* BashExecutionMessage is treated like a user message for turn boundaries.
|
|
91
|
-
*/
|
|
92
|
-
export declare function findTurnStartIndex(entries: SessionEntry[], entryIndex: number, startIndex: number): number;
|
|
93
|
-
export interface CutPointResult {
|
|
94
|
-
/** Index of first entry to keep */
|
|
95
|
-
firstKeptEntryIndex: number;
|
|
96
|
-
/** Index of user message that starts the turn being split, or -1 if not splitting */
|
|
97
|
-
turnStartIndex: number;
|
|
98
|
-
/** Whether this cut splits a turn (cut point is not a user message) */
|
|
99
|
-
isSplitTurn: boolean;
|
|
100
|
-
}
|
|
101
|
-
export interface FindCutPointOptions {
|
|
102
|
-
/**
|
|
103
|
-
* Explicit phase-boundary compaction should prefer the newest safe boundary
|
|
104
|
-
* over retaining a large just-finished turn as the recent raw suffix.
|
|
105
|
-
*/
|
|
106
|
-
phaseBoundary?: boolean;
|
|
107
|
-
/**
|
|
108
|
-
* When provided, use this entry id as a fixed cut point instead of walking
|
|
109
|
-
* backwards from the newest entry. This lets request-time adapters freeze a
|
|
110
|
-
* previously-computed cut without regenerating the summary.
|
|
111
|
-
*/
|
|
112
|
-
anchorEntryId?: string;
|
|
113
|
-
/**
|
|
114
|
-
* When true, ensure the most recent user message is never folded into the
|
|
115
|
-
* compaction summary — the cut point is pulled back to (or before) the
|
|
116
|
-
* latest user message so it survives verbatim. This protects the current
|
|
117
|
-
* task/brief from being reduced to a truncated excerpt mid-run.
|
|
118
|
-
*/
|
|
119
|
-
pinLatestUserMessage?: boolean;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Find the cut point in session entries that keeps approximately `keepRecentTokens`.
|
|
123
|
-
*
|
|
124
|
-
* Algorithm: Walk backwards from newest, accumulating estimated message sizes.
|
|
125
|
-
* Stop when we've accumulated >= keepRecentTokens. Cut at that point.
|
|
126
|
-
*
|
|
127
|
-
* Can cut at user OR assistant messages (never tool results). When cutting at an
|
|
128
|
-
* assistant message with tool calls, its tool results come after and will be kept.
|
|
129
|
-
*
|
|
130
|
-
* Returns CutPointResult with:
|
|
131
|
-
* - firstKeptEntryIndex: the entry index to start keeping from
|
|
132
|
-
* - turnStartIndex: if cutting mid-turn, the user message that started that turn
|
|
133
|
-
* - isSplitTurn: whether we're cutting in the middle of a turn
|
|
134
|
-
*
|
|
135
|
-
* Only considers entries between `startIndex` and `endIndex` (exclusive).
|
|
136
|
-
*/
|
|
137
|
-
export declare function findCutPoint(entries: SessionEntry[], startIndex: number, endIndex: number, keepRecentTokens: number, options?: FindCutPointOptions): CutPointResult;
|
|
138
|
-
/**
|
|
139
|
-
* Generate a summary of the conversation using the LLM.
|
|
140
|
-
* If previousSummary is provided, uses the update prompt to merge.
|
|
141
|
-
*
|
|
142
|
-
* @deprecated The active coding-agent session path uses deterministic DCP-lite
|
|
143
|
-
* (`compactDcpLite`) plus `session_before_compact` hook details. This legacy
|
|
144
|
-
* LLM summarizer remains exported for compatibility with older callers only.
|
|
145
|
-
*/
|
|
146
|
-
export declare function generateSummary(currentMessages: AgentMessage[], model: Model<any>, reserveTokens: number, apiKey: string | undefined, headers?: Record<string, string>, signal?: AbortSignal, customInstructions?: string, previousSummary?: string, thinkingLevel?: ThinkingLevel, streamFn?: StreamFn): Promise<string>;
|
|
147
58
|
export interface CompactionPreparation {
|
|
148
59
|
/** UUID of first entry to keep */
|
|
149
60
|
firstKeptEntryId: string;
|
|
@@ -179,29 +90,6 @@ export interface PrepareCompactionOptions {
|
|
|
179
90
|
pinLatestUserMessage?: boolean;
|
|
180
91
|
}
|
|
181
92
|
export declare function prepareCompaction(pathEntries: SessionEntry[], settings: CompactionSettings, options?: PrepareCompactionOptions): CompactionPreparation | undefined;
|
|
182
|
-
export declare function estimateTextTokens(text: string): number;
|
|
183
|
-
export declare function estimateCompactionTokenMetrics(preparation: Pick<CompactionPreparation, "messagesToSummarize" | "turnPrefixMessages"> & Partial<Pick<CompactionPreparation, "compactionNumber">>, summary: string): Pick<CompactionResult, "tokensCompacted" | "tokensRemoved" | "summaryTokens" | "reductionPercent" | "compactionNumber" | "largestTokenSources">;
|
|
184
|
-
/**
|
|
185
|
-
* Deduplicate repeated tool calls in a message array by keeping only the
|
|
186
|
-
* most recent occurrence of each (tool, args) pair.
|
|
187
|
-
*
|
|
188
|
-
* Strategy:
|
|
189
|
-
* - **Idempotent-read tools** (read, grep, glob): same (name, args) → keep last only.
|
|
190
|
-
* These tools return the same content for the same arguments.
|
|
191
|
-
* - **Output-dependent tools** (bash): same (name, args, output) → keep last only.
|
|
192
|
-
* Two bash calls with same command but different output are NOT duplicates.
|
|
193
|
-
* - **Mutating tools** (edit, write): never deduplicated. Chronological ordering
|
|
194
|
-
* of mutations matters for correctness.
|
|
195
|
-
* - **Unknown tools** (extensions, MCP, custom): never deduplicated. Conservative
|
|
196
|
-
* by default — only tools in the known sets above participate.
|
|
197
|
-
*
|
|
198
|
-
* Deduplication removes both the ToolCall block from the assistant message
|
|
199
|
-
* and the corresponding ToolResultMessage from the array.
|
|
200
|
-
*
|
|
201
|
-
* Recalculated each time compaction runs — prompt cache is only impacted
|
|
202
|
-
* alongside compression, not on every turn.
|
|
203
|
-
*/
|
|
204
|
-
export declare function deduplicateToolCalls(messages: AgentMessage[]): AgentMessage[];
|
|
205
93
|
/**
|
|
206
94
|
* Generate summaries for compaction using prepared data.
|
|
207
95
|
* Returns CompactionResult - SessionManager adds uuid/parentUuid when saving.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../../../src/sdk/coding-agent/core/compaction/compaction.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC1F,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../../../src/sdk/coding-agent/core/compaction/compaction.ts"],"names":[],"mappings":"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"}
|