neoctl 0.2.0 → 0.2.1
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/README.md +20 -9
- package/dist/context/compaction.d.ts +3 -0
- package/dist/context/compaction.js +231 -40
- package/dist/context/compaction.js.map +1 -1
- package/dist/context/prompts.js +4 -4
- package/dist/context/prompts.js.map +1 -1
- package/dist/core/commands.d.ts +66 -0
- package/dist/core/commands.js +151 -0
- package/dist/core/commands.js.map +1 -0
- package/dist/core/context-metrics.d.ts +5 -2
- package/dist/core/context-metrics.js +85 -9
- package/dist/core/context-metrics.js.map +1 -1
- package/dist/core/image-registry.d.ts +42 -0
- package/dist/core/image-registry.js +128 -0
- package/dist/core/image-registry.js.map +1 -0
- package/dist/core/message-pipeline.d.ts +6 -0
- package/dist/core/message-pipeline.js +12 -0
- package/dist/core/message-pipeline.js.map +1 -1
- package/dist/core/query-engine.d.ts +3 -5
- package/dist/core/query-engine.js +35 -48
- package/dist/core/query-engine.js.map +1 -1
- package/dist/core/query.d.ts +1 -5
- package/dist/core/query.js +21 -8
- package/dist/core/query.js.map +1 -1
- package/dist/core/runtime.d.ts +59 -0
- package/dist/core/runtime.js +161 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/core/state.d.ts +6 -7
- package/dist/core/state.js +2 -0
- package/dist/core/state.js.map +1 -1
- package/dist/index.d.ts +14 -10
- package/dist/index.js +14 -10
- package/dist/index.js.map +1 -1
- package/dist/model/anthropic-adapter.d.ts +30 -0
- package/dist/model/anthropic-adapter.js +106 -0
- package/dist/model/anthropic-adapter.js.map +1 -0
- package/dist/model/anthropic-mapper.d.ts +13 -0
- package/dist/model/anthropic-mapper.js +482 -0
- package/dist/model/anthropic-mapper.js.map +1 -0
- package/dist/model/config.d.ts +8 -2
- package/dist/model/config.js +24 -1
- package/dist/model/config.js.map +1 -1
- package/dist/model/model-gateway.js +1 -1
- package/dist/model/model-gateway.js.map +1 -1
- package/dist/model/openai-mappers.js +1 -1
- package/dist/model/openai-mappers.js.map +1 -1
- package/dist/model/provider-factory.js +17 -0
- package/dist/model/provider-factory.js.map +1 -1
- package/dist/model/smoke-anthropic-mapper.d.ts +1 -0
- package/dist/model/smoke-anthropic-mapper.js +85 -0
- package/dist/model/smoke-anthropic-mapper.js.map +1 -0
- package/dist/repl/index.js +77 -70
- package/dist/repl/index.js.map +1 -1
- package/dist/repl/markdown-renderer.d.ts +19 -0
- package/dist/repl/markdown-renderer.js +58 -3
- package/dist/repl/markdown-renderer.js.map +1 -1
- package/dist/repl/transcript-flush.d.ts +6 -0
- package/dist/repl/transcript-flush.js +54 -0
- package/dist/repl/transcript-flush.js.map +1 -0
- package/dist/repl/transcript-format.d.ts +16 -0
- package/dist/repl/transcript-format.js +199 -0
- package/dist/repl/transcript-format.js.map +1 -0
- package/dist/server/agent-manager.d.ts +56 -0
- package/dist/server/agent-manager.js +171 -0
- package/dist/server/agent-manager.js.map +1 -0
- package/dist/server/connection-manager.d.ts +18 -0
- package/dist/server/connection-manager.js +52 -0
- package/dist/server/connection-manager.js.map +1 -0
- package/dist/server/event-mapper.d.ts +4 -0
- package/dist/server/event-mapper.js +31 -0
- package/dist/server/event-mapper.js.map +1 -0
- package/dist/server/query-runtime.d.ts +29 -0
- package/dist/server/query-runtime.js +61 -0
- package/dist/server/query-runtime.js.map +1 -0
- package/dist/server/rpc-router.d.ts +24 -0
- package/dist/server/rpc-router.js +165 -0
- package/dist/server/rpc-router.js.map +1 -0
- package/dist/server/rpc-types.d.ts +92 -0
- package/dist/server/rpc-types.js +2 -0
- package/dist/server/rpc-types.js.map +1 -0
- package/dist/server/ws-server.d.ts +22 -0
- package/dist/server/ws-server.js +84 -0
- package/dist/server/ws-server.js.map +1 -0
- package/dist/session/session-export.d.ts +0 -1
- package/dist/session/session-export.js +1 -2
- package/dist/session/session-export.js.map +1 -1
- package/dist/skills/skill-tool.js +1 -1
- package/dist/skills/skill-tool.js.map +1 -1
- package/dist/tasks/task-record.d.ts +50 -0
- package/dist/tasks/task-record.js +50 -0
- package/dist/tasks/task-record.js.map +1 -0
- package/dist/tasks/task-store.d.ts +9 -23
- package/dist/tasks/task-store.js +2 -37
- package/dist/tasks/task-store.js.map +1 -1
- package/dist/tasks/task-tools.d.ts +3 -18
- package/dist/tasks/task-tools.js +9 -89
- package/dist/tasks/task-tools.js.map +1 -1
- package/dist/tips.js +6 -6
- package/dist/tips.js.map +1 -1
- package/dist/tools/builtins/exec-tool.js +2 -2
- package/dist/tools/builtins/exec-tool.js.map +1 -1
- package/dist/tools/builtins/image-loader-tool.d.ts +22 -0
- package/dist/tools/builtins/image-loader-tool.js +235 -0
- package/dist/tools/builtins/image-loader-tool.js.map +1 -0
- package/dist/types/messages.d.ts +0 -1
- package/dist/types/messages.js.map +1 -1
- package/dist/web/html.js +3 -4
- package/dist/web/html.js.map +1 -1
- package/dist/web/index.d.ts +11 -5
- package/dist/web/index.js +68 -28
- package/dist/web/index.js.map +1 -1
- package/package.json +3 -1
package/dist/context/prompts.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const SYSTEM_PROMPT_DYNAMIC_BOUNDARY = "__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__";
|
|
2
2
|
export function buildDefaultSystemPromptSections(enabledTools = []) {
|
|
3
3
|
const hasImageGenerationTool = enabledTools.includes("image2");
|
|
4
|
-
const
|
|
4
|
+
const hasLoadImageTool = enabledTools.includes("load_image");
|
|
5
5
|
return [
|
|
6
6
|
{
|
|
7
7
|
name: "Agent Scaffold",
|
|
@@ -30,9 +30,9 @@ export function buildDefaultSystemPromptSections(enabledTools = []) {
|
|
|
30
30
|
? `Available tools are provided separately. Stable tool prefix: ${enabledTools.join(", ")}.`
|
|
31
31
|
: "Available tools are provided separately by the runtime.",
|
|
32
32
|
"When using tools, you may briefly state the intent of the tool call; if a tool result contains valuable information, you may briefly report it.",
|
|
33
|
-
|
|
34
|
-
? "When
|
|
35
|
-
: "This runtime has no
|
|
33
|
+
hasLoadImageTool
|
|
34
|
+
? "When you need to inspect, describe, OCR, or answer questions about any image (including historical images from earlier in the conversation that may have been compacted), use the load_image tool with image ids (e.g. img_1) or labels. This loads the actual image pixels directly into your context so you can see them with your own multimodal capabilities. The image registry in compact boundary messages lists all available historical images."
|
|
35
|
+
: "This runtime has no image loading tool. Do not pretend to visually inspect stored image paths; ask the user to switch to a vision-capable model/runtime if visual analysis is required.",
|
|
36
36
|
hasImageGenerationTool
|
|
37
37
|
? "When the user asks for drawing/image generation or image editing/modification, use the image2 tool. It is backed by OpenAI's Images API, defaults to OpenAI model gpt-image-2, and supports mode=generate for new images and mode=edit for modifying existing images. If image2 validation fails, tell the user the model and exact parameter reason from the tool result."
|
|
38
38
|
: "This runtime has no drawing/image generation/editing tool. If the user asks you to draw, create, render, generate, or edit an image, say that the current model/provider does not have drawing capability instead of pretending to generate one.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/context/prompts.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,8BAA8B,GAAG,oCAAoC,CAAC;AAkBnF,MAAM,UAAU,gCAAgC,CAAC,eAAkC,EAAE;IACnF,MAAM,sBAAsB,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC/D,MAAM,
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/context/prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export type ModelReasoningArgument = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | "default" | "off";
|
|
2
|
+
export type RuntimeCommand = {
|
|
3
|
+
type: "help";
|
|
4
|
+
} | {
|
|
5
|
+
type: "cost";
|
|
6
|
+
} | {
|
|
7
|
+
type: "compact";
|
|
8
|
+
} | {
|
|
9
|
+
type: "pure";
|
|
10
|
+
} | {
|
|
11
|
+
type: "env";
|
|
12
|
+
} | {
|
|
13
|
+
type: "exit";
|
|
14
|
+
} | {
|
|
15
|
+
type: "export";
|
|
16
|
+
path: string;
|
|
17
|
+
} | {
|
|
18
|
+
type: "login";
|
|
19
|
+
} | {
|
|
20
|
+
type: "log";
|
|
21
|
+
path?: string;
|
|
22
|
+
off?: boolean;
|
|
23
|
+
} | {
|
|
24
|
+
type: "model";
|
|
25
|
+
model?: string;
|
|
26
|
+
reasoning?: ModelReasoningArgument;
|
|
27
|
+
} | {
|
|
28
|
+
type: "new";
|
|
29
|
+
} | {
|
|
30
|
+
type: "reset";
|
|
31
|
+
} | {
|
|
32
|
+
type: "sessions";
|
|
33
|
+
} | {
|
|
34
|
+
type: "state";
|
|
35
|
+
} | {
|
|
36
|
+
type: "input";
|
|
37
|
+
text: string;
|
|
38
|
+
};
|
|
39
|
+
export type RuntimeCommandArgumentSpec = "none" | "required" | "optional" | "log";
|
|
40
|
+
export interface RuntimeCommandDefinition {
|
|
41
|
+
name: string;
|
|
42
|
+
usage: string;
|
|
43
|
+
description: string;
|
|
44
|
+
arguments: RuntimeCommandArgumentSpec;
|
|
45
|
+
aliases?: string[];
|
|
46
|
+
}
|
|
47
|
+
export declare const runtimeCommandDefinitions: RuntimeCommandDefinition[];
|
|
48
|
+
export declare const commandUsages: string[];
|
|
49
|
+
export declare function parseRuntimeCommand(line: string): RuntimeCommand;
|
|
50
|
+
export declare function isValidRuntimeCommandLine(line: string): boolean;
|
|
51
|
+
export declare function isModelReasoningArgument(value: string): value is ModelReasoningArgument;
|
|
52
|
+
export declare const runtimeHelpText: string;
|
|
53
|
+
export interface CliRuntimeCommandParseResult {
|
|
54
|
+
line: string;
|
|
55
|
+
definition: RuntimeCommandDefinition;
|
|
56
|
+
}
|
|
57
|
+
export declare function parseCliRuntimeCommandArgs(argv: string[]): CliRuntimeCommandParseResult | undefined;
|
|
58
|
+
export declare function cliHelpText(binaryName?: string): string;
|
|
59
|
+
export type ReplCommand = RuntimeCommand;
|
|
60
|
+
export type ReplCommandArgumentSpec = RuntimeCommandArgumentSpec;
|
|
61
|
+
export type ReplCommandDefinition = RuntimeCommandDefinition;
|
|
62
|
+
export declare const replCommandDefinitions: RuntimeCommandDefinition[];
|
|
63
|
+
export declare const helpText: string;
|
|
64
|
+
export declare const parseReplCommand: typeof parseRuntimeCommand;
|
|
65
|
+
export declare const isValidReplCommandLine: typeof isValidRuntimeCommandLine;
|
|
66
|
+
export declare const parseCliReplCommandArgs: typeof parseCliRuntimeCommandArgs;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
export const runtimeCommandDefinitions = [
|
|
2
|
+
{ name: "/help", usage: "/help", description: "Show commands", arguments: "none" },
|
|
3
|
+
{ name: "/cost", usage: "/cost", description: "Show total token usage for this session", arguments: "none" },
|
|
4
|
+
{ name: "/compact", usage: "/compact", description: "Manually compact earlier context", arguments: "none" },
|
|
5
|
+
{ name: "/pure", usage: "/pure", description: "Sanitize context after WAF/risk blocks without resetting", arguments: "none" },
|
|
6
|
+
{ name: "/export", usage: "/export <absolute-md-path>", description: "Export the current session transcript as detailed Markdown", arguments: "required" },
|
|
7
|
+
{ name: "/env", usage: "/env", description: "Open the neoctl configuration directory", arguments: "none" },
|
|
8
|
+
{ name: "/login", usage: "/login", description: "Configure and save a model provider to the env file", arguments: "none" },
|
|
9
|
+
{ name: "/model", usage: "/model [model-id] [effort|default|off]", description: "Show or switch model and supported reasoning effort", arguments: "optional" },
|
|
10
|
+
{ name: "/new", usage: "/new", description: "Start a new session; running current session continues in background", arguments: "none" },
|
|
11
|
+
{ name: "/log", usage: "/log <dir>", description: "Write model communication logs to an absolute directory", arguments: "required" },
|
|
12
|
+
{ name: "/log off", usage: "/log off", description: "Disable model communication logs", arguments: "none" },
|
|
13
|
+
{ name: "/sessions", usage: "/sessions", description: "Browse saved sessions", arguments: "none" },
|
|
14
|
+
{ name: "/state", usage: "/state", description: "Show query engine state", arguments: "none" },
|
|
15
|
+
{ name: "/reset", usage: "/reset", description: "Clear current transcript and add a reset marker", arguments: "none" },
|
|
16
|
+
{ name: "/exit", usage: "/exit", description: "Quit", arguments: "none", aliases: ["/quit"] },
|
|
17
|
+
];
|
|
18
|
+
export const commandUsages = runtimeCommandDefinitions.map((command) => command.usage);
|
|
19
|
+
export function parseRuntimeCommand(line) {
|
|
20
|
+
const parsed = parseSlashCommandLine(line);
|
|
21
|
+
if (!parsed.valid)
|
|
22
|
+
return { type: "input", text: line };
|
|
23
|
+
const { name, argument } = parsed;
|
|
24
|
+
if (name === "/help")
|
|
25
|
+
return { type: "help" };
|
|
26
|
+
if (name === "/cost")
|
|
27
|
+
return { type: "cost" };
|
|
28
|
+
if (name === "/compact")
|
|
29
|
+
return { type: "compact" };
|
|
30
|
+
if (name === "/pure")
|
|
31
|
+
return { type: "pure" };
|
|
32
|
+
if (name === "/export")
|
|
33
|
+
return { type: "export", path: argument };
|
|
34
|
+
if (name === "/env")
|
|
35
|
+
return { type: "env" };
|
|
36
|
+
if (name === "/login")
|
|
37
|
+
return { type: "login" };
|
|
38
|
+
if (name === "/exit" || name === "/quit")
|
|
39
|
+
return { type: "exit" };
|
|
40
|
+
if (name === "/model")
|
|
41
|
+
return parseModelCommand(argument) ?? { type: "input", text: line };
|
|
42
|
+
if (name === "/new")
|
|
43
|
+
return { type: "new" };
|
|
44
|
+
if (name === "/log") {
|
|
45
|
+
if (argument.toLowerCase() === "off")
|
|
46
|
+
return { type: "log", off: true };
|
|
47
|
+
return { type: "log", path: argument };
|
|
48
|
+
}
|
|
49
|
+
if (name === "/reset")
|
|
50
|
+
return { type: "reset" };
|
|
51
|
+
if (name === "/sessions")
|
|
52
|
+
return { type: "sessions" };
|
|
53
|
+
if (name === "/state")
|
|
54
|
+
return { type: "state" };
|
|
55
|
+
return { type: "input", text: line };
|
|
56
|
+
}
|
|
57
|
+
export function isValidRuntimeCommandLine(line) {
|
|
58
|
+
return parseSlashCommandLine(line).valid && parseRuntimeCommand(line).type !== "input";
|
|
59
|
+
}
|
|
60
|
+
export function isModelReasoningArgument(value) {
|
|
61
|
+
return value === "none" || value === "minimal" || value === "low" || value === "medium" || value === "high" || value === "xhigh" || value === "max" || value === "default" || value === "off";
|
|
62
|
+
}
|
|
63
|
+
function parseModelCommand(argument) {
|
|
64
|
+
const tokens = argument.split(/\s+/).filter(Boolean);
|
|
65
|
+
if (tokens.length === 0)
|
|
66
|
+
return { type: "model" };
|
|
67
|
+
if (tokens.length > 2)
|
|
68
|
+
return undefined;
|
|
69
|
+
if (tokens.length === 1) {
|
|
70
|
+
const [single] = tokens;
|
|
71
|
+
return isModelReasoningArgument(single)
|
|
72
|
+
? { type: "model", reasoning: single }
|
|
73
|
+
: { type: "model", model: single };
|
|
74
|
+
}
|
|
75
|
+
const [model, reasoning] = tokens;
|
|
76
|
+
if (!isModelReasoningArgument(reasoning))
|
|
77
|
+
return undefined;
|
|
78
|
+
return { type: "model", model, reasoning };
|
|
79
|
+
}
|
|
80
|
+
function parseSlashCommandLine(line) {
|
|
81
|
+
if (!line.startsWith("/"))
|
|
82
|
+
return { valid: false };
|
|
83
|
+
const trimmed = line.trimEnd();
|
|
84
|
+
const match = /^(\/\S+)(?:\s+(.*))?$/.exec(trimmed);
|
|
85
|
+
if (!match)
|
|
86
|
+
return { valid: false };
|
|
87
|
+
const typedName = match[1].toLowerCase();
|
|
88
|
+
const argument = match[2]?.trim() ?? "";
|
|
89
|
+
const definition = runtimeCommandDefinitions.find((command) => command.name.toLowerCase() === typedName || command.aliases?.some((alias) => alias.toLowerCase() === typedName));
|
|
90
|
+
if (!definition)
|
|
91
|
+
return { valid: false };
|
|
92
|
+
if (definition.arguments === "none" && argument.length > 0)
|
|
93
|
+
return { valid: false };
|
|
94
|
+
if (definition.arguments === "required" && argument.length === 0)
|
|
95
|
+
return { valid: false };
|
|
96
|
+
if (definition.arguments === "log" && argument.length === 0)
|
|
97
|
+
return { valid: false };
|
|
98
|
+
return { valid: true, name: typedName, argument };
|
|
99
|
+
}
|
|
100
|
+
const helpUsageWidth = Math.max(...runtimeCommandDefinitions.map((command) => command.usage.length));
|
|
101
|
+
export const runtimeHelpText = [
|
|
102
|
+
"Commands:",
|
|
103
|
+
...runtimeCommandDefinitions.map((command) => ` ${command.usage.padEnd(helpUsageWidth)} ${command.description}`),
|
|
104
|
+
].join("\n");
|
|
105
|
+
export function parseCliRuntimeCommandArgs(argv) {
|
|
106
|
+
if (argv.length === 0)
|
|
107
|
+
return undefined;
|
|
108
|
+
const first = argv[0];
|
|
109
|
+
const match = /^--?([^=\s]+)(?:=(.*))?$/.exec(first);
|
|
110
|
+
if (!match)
|
|
111
|
+
return undefined;
|
|
112
|
+
const commandName = `/${match[1].toLowerCase()}`;
|
|
113
|
+
const definition = runtimeCommandDefinitions.find((command) => command.name.toLowerCase() === commandName || command.aliases?.some((alias) => alias.toLowerCase() === commandName));
|
|
114
|
+
if (!definition)
|
|
115
|
+
return undefined;
|
|
116
|
+
const inlineArgument = match[2];
|
|
117
|
+
const rest = inlineArgument === undefined ? argv.slice(1) : [inlineArgument, ...argv.slice(1)];
|
|
118
|
+
if (definition.arguments === "none" && rest.length > 0)
|
|
119
|
+
return undefined;
|
|
120
|
+
if ((definition.arguments === "required" || definition.arguments === "log") && rest.length === 0)
|
|
121
|
+
return undefined;
|
|
122
|
+
const line = rest.length === 0 ? definition.name : `${definition.name} ${rest.join(" ")}`;
|
|
123
|
+
return { line, definition };
|
|
124
|
+
}
|
|
125
|
+
export function cliHelpText(binaryName = "neo") {
|
|
126
|
+
const cliCommandUsages = runtimeCommandDefinitions.map((command) => command.usage.replace(/^\//, "-"));
|
|
127
|
+
const cliUsageWidth = Math.max(...cliCommandUsages.map((usage) => usage.length));
|
|
128
|
+
return [
|
|
129
|
+
`Usage: ${binaryName} [command]`,
|
|
130
|
+
"",
|
|
131
|
+
"CLI commands mirror slash commands; use '-' or '--' in place of '/'.",
|
|
132
|
+
"",
|
|
133
|
+
"Commands:",
|
|
134
|
+
...runtimeCommandDefinitions.map((command) => {
|
|
135
|
+
const usage = command.usage.replace(/^\//, "-");
|
|
136
|
+
return ` ${usage.padEnd(cliUsageWidth)} ${command.description}`;
|
|
137
|
+
}),
|
|
138
|
+
"",
|
|
139
|
+
"Examples:",
|
|
140
|
+
` ${binaryName} -help`,
|
|
141
|
+
` ${binaryName} -model`,
|
|
142
|
+
` ${binaryName} -model gpt-5.5 high`,
|
|
143
|
+
` ${binaryName} -new`,
|
|
144
|
+
].join("\n");
|
|
145
|
+
}
|
|
146
|
+
export const replCommandDefinitions = runtimeCommandDefinitions;
|
|
147
|
+
export const helpText = runtimeHelpText;
|
|
148
|
+
export const parseReplCommand = parseRuntimeCommand;
|
|
149
|
+
export const isValidReplCommandLine = isValidRuntimeCommandLine;
|
|
150
|
+
export const parseCliReplCommandArgs = parseCliRuntimeCommandArgs;
|
|
151
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/core/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { ToolDefinition } from "../tools/tool.js";
|
|
2
2
|
import type { ContextMetrics } from "../types/events.js";
|
|
3
3
|
import type { Message } from "../types/messages.js";
|
|
4
|
-
export
|
|
4
|
+
export interface BuildContextMetricsInput {
|
|
5
5
|
model?: string;
|
|
6
6
|
messages: readonly Message[];
|
|
7
7
|
systemPrompt: string;
|
|
8
8
|
tools: readonly ToolDefinition[];
|
|
9
|
-
|
|
9
|
+
cachedToolsAndPromptTokens?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function buildContextMetrics(input: BuildContextMetricsInput): ContextMetrics;
|
|
10
12
|
export declare function estimateTextTokens(text: string): number;
|
|
13
|
+
export declare function computeStaticTokens(systemPrompt: string, tools: readonly ToolDefinition[]): number;
|
|
@@ -1,12 +1,61 @@
|
|
|
1
1
|
import { resolveContextWindowTokens } from "../model/context-window.js";
|
|
2
|
+
let _encode;
|
|
3
|
+
let _encoderLoadFailed = false;
|
|
4
|
+
function getEncoder() {
|
|
5
|
+
if (_encode || _encoderLoadFailed)
|
|
6
|
+
return _encode;
|
|
7
|
+
try {
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
9
|
+
const mod = require("gpt-tokenizer");
|
|
10
|
+
_encode = mod.encode ?? mod.default?.encode;
|
|
11
|
+
if (!_encode)
|
|
12
|
+
_encoderLoadFailed = true;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
_encoderLoadFailed = true;
|
|
16
|
+
}
|
|
17
|
+
return _encode;
|
|
18
|
+
}
|
|
19
|
+
const TOKEN_CACHE_MAX = 128;
|
|
20
|
+
const _tokenCache = new Map();
|
|
21
|
+
function cachedTokenCount(text) {
|
|
22
|
+
if (!text)
|
|
23
|
+
return 0;
|
|
24
|
+
const cacheKey = text.length <= 4096 ? text : undefined;
|
|
25
|
+
if (cacheKey) {
|
|
26
|
+
const cached = _tokenCache.get(cacheKey);
|
|
27
|
+
if (cached !== undefined)
|
|
28
|
+
return cached;
|
|
29
|
+
}
|
|
30
|
+
const encode = getEncoder();
|
|
31
|
+
const count = encode ? encode(text).length : heuristicTokenCount(text);
|
|
32
|
+
if (cacheKey) {
|
|
33
|
+
if (_tokenCache.size >= TOKEN_CACHE_MAX) {
|
|
34
|
+
const first = _tokenCache.keys().next().value;
|
|
35
|
+
if (first !== undefined)
|
|
36
|
+
_tokenCache.delete(first);
|
|
37
|
+
}
|
|
38
|
+
_tokenCache.set(cacheKey, count);
|
|
39
|
+
}
|
|
40
|
+
return count;
|
|
41
|
+
}
|
|
2
42
|
export function buildContextMetrics(input) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
43
|
+
let estimatedInputTokens;
|
|
44
|
+
let estimatedChars;
|
|
45
|
+
if (input.cachedToolsAndPromptTokens !== undefined) {
|
|
46
|
+
const messageSerialized = input.messages.map(serializeMessageForMetrics).join("\n");
|
|
47
|
+
estimatedChars = input.systemPrompt.length + messageSerialized.length;
|
|
48
|
+
estimatedInputTokens = input.cachedToolsAndPromptTokens + estimateTextTokens(messageSerialized);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
const serialized = [
|
|
52
|
+
input.systemPrompt,
|
|
53
|
+
...input.messages.map(serializeMessageForMetrics),
|
|
54
|
+
JSON.stringify(input.tools.map((tool) => ({ name: tool.name, description: tool.description, parameters: tool.inputSchema }))),
|
|
55
|
+
].join("\n");
|
|
56
|
+
estimatedChars = serialized.length;
|
|
57
|
+
estimatedInputTokens = estimateTextTokens(serialized);
|
|
58
|
+
}
|
|
10
59
|
const window = resolveContextWindowTokens(input.model);
|
|
11
60
|
return {
|
|
12
61
|
model: input.model,
|
|
@@ -31,6 +80,21 @@ export function buildContextMetrics(input) {
|
|
|
31
80
|
};
|
|
32
81
|
}
|
|
33
82
|
export function estimateTextTokens(text) {
|
|
83
|
+
if (!text)
|
|
84
|
+
return 0;
|
|
85
|
+
if (text.length <= 8192)
|
|
86
|
+
return cachedTokenCount(text);
|
|
87
|
+
let total = 0;
|
|
88
|
+
for (let i = 0; i < text.length; i += 8192) {
|
|
89
|
+
total += cachedTokenCount(text.slice(i, i + 8192));
|
|
90
|
+
}
|
|
91
|
+
return total;
|
|
92
|
+
}
|
|
93
|
+
export function computeStaticTokens(systemPrompt, tools) {
|
|
94
|
+
const toolsSerialized = JSON.stringify(tools.map((tool) => ({ name: tool.name, description: tool.description, parameters: tool.inputSchema })));
|
|
95
|
+
return estimateTextTokens(systemPrompt) + estimateTextTokens(toolsSerialized);
|
|
96
|
+
}
|
|
97
|
+
function heuristicTokenCount(text) {
|
|
34
98
|
if (!text)
|
|
35
99
|
return 0;
|
|
36
100
|
let tokens = 0;
|
|
@@ -63,11 +127,23 @@ export function estimateTextTokens(text) {
|
|
|
63
127
|
function serializeMessageForMetrics(message) {
|
|
64
128
|
return `${message.role}: ${message.blocks.map(serializeBlockForMetrics).join("\n")}`;
|
|
65
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Most vision APIs charge ~85 tokens per tile (typically 512x512).
|
|
132
|
+
* A typical base64 image of ~200KB decodes to roughly 150K pixels ≈ ~1 tile ≈ 85 tokens.
|
|
133
|
+
* Larger images get more tiles. We estimate based on base64 length as a proxy for pixel count.
|
|
134
|
+
*/
|
|
135
|
+
function estimateImageTokens(base64Length) {
|
|
136
|
+
const estimatedBytes = Math.floor(base64Length * 0.75);
|
|
137
|
+
const tiles = Math.max(1, Math.ceil(estimatedBytes / 200_000));
|
|
138
|
+
return tiles * 85;
|
|
139
|
+
}
|
|
66
140
|
function serializeBlockForMetrics(block) {
|
|
67
141
|
if (block.type === "text")
|
|
68
142
|
return block.text;
|
|
69
|
-
if (block.type === "image")
|
|
70
|
-
|
|
143
|
+
if (block.type === "image") {
|
|
144
|
+
const imageTokens = estimateImageTokens(block.data.length);
|
|
145
|
+
return `${"x".repeat(imageTokens * 4)}`;
|
|
146
|
+
}
|
|
71
147
|
if (block.type === "thinking")
|
|
72
148
|
return block.text;
|
|
73
149
|
if (block.type === "tool_use")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-metrics.js","sourceRoot":"","sources":["../../src/core/context-metrics.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAExE,MAAM,UAAU,mBAAmB,CAAC,
|
|
1
|
+
{"version":3,"file":"context-metrics.js","sourceRoot":"","sources":["../../src/core/context-metrics.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAExE,IAAI,OAAiD,CAAC;AACtD,IAAI,kBAAkB,GAAG,KAAK,CAAC;AAE/B,SAAS,UAAU;IACjB,IAAI,OAAO,IAAI,kBAAkB;QAAE,OAAO,OAAO,CAAC;IAClD,IAAI,CAAC;QACH,iEAAiE;QACjE,MAAM,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;QACrC,OAAO,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC;QAC5C,IAAI,CAAC,OAAO;YAAE,kBAAkB,GAAG,IAAI,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,kBAAkB,GAAG,IAAI,CAAC;IAC5B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,eAAe,GAAG,GAAG,CAAC;AAC5B,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE9C,SAAS,gBAAgB,CAAC,IAAY;IACpC,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACxD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;IAC1C,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACvE,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,WAAW,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC;YACxC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAC9C,IAAI,KAAK,KAAK,SAAS;gBAAE,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrD,CAAC;QACD,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAUD,MAAM,UAAU,mBAAmB,CAAC,KAA+B;IACjE,IAAI,oBAA4B,CAAC;IACjC,IAAI,cAAsB,CAAC;IAE3B,IAAI,KAAK,CAAC,0BAA0B,KAAK,SAAS,EAAE,CAAC;QACnD,MAAM,iBAAiB,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpF,cAAc,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC;QACtE,oBAAoB,GAAG,KAAK,CAAC,0BAA0B,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;IAClG,CAAC;SAAM,CAAC;QACN,MAAM,UAAU,GAAG;YACjB,KAAK,CAAC,YAAY;YAClB,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,0BAA0B,CAAC;YACjD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;SAC9H,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC;QACnC,oBAAoB,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,MAAM,GAAG,0BAA0B,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACvD,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,oBAAoB;QACpB,cAAc;QACd,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM;QACnC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;QAC7B,mBAAmB,EAAE,MAAM,CAAC,MAAM;QAClC,mBAAmB,EAAE,MAAM,CAAC,MAAM;QAClC,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,oBAAoB,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;QACnF,aAAa,EAAE,MAAM,CAAC,KAAK;YACzB,CAAC,CAAC;gBACE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE;gBACnB,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ;gBAC/B,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,eAAe;gBAC7C,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,eAAe;gBAC7C,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS;gBACjC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU;gBACnC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;aAC5B;YACH,CAAC,CAAC,SAAS;KACd,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI;QAAE,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC3C,KAAK,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,YAAoB,EAAE,KAAgC;IACxF,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IAChJ,OAAO,kBAAkB,CAAC,YAAY,CAAC,GAAG,kBAAkB,CAAC,eAAe,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY;IACvC,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;YACrC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;YAClC,QAAQ,GAAG,CAAC,CAAC;YACb,MAAM,IAAI,CAAC,CAAC;YACZ,SAAS;QACX,CAAC;QACD,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM;YACpE,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;YACzE,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;YAClC,QAAQ,GAAG,CAAC,CAAC;YACb,MAAM,IAAI,CAAC,CAAC;YACZ,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;YAClC,QAAQ,GAAG,CAAC,CAAC;YACb,SAAS;QACX,CAAC;QACD,QAAQ,IAAI,CAAC,CAAC;IAChB,CAAC;IAED,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;IAClC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,0BAA0B,CAAC,OAAgB;IAClD,OAAO,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACvF,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,YAAoB;IAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAC/D,OAAO,KAAK,GAAG,EAAE,CAAC;AACpB,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAmB;IACnD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC;IAC7C,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3D,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,CAAC;IAC1C,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC;IACjD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,YAAY,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;IAC9F,OAAO,eAAe,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Message } from "../types/messages.js";
|
|
2
|
+
export interface ImageEntry {
|
|
3
|
+
id: string;
|
|
4
|
+
label?: string;
|
|
5
|
+
mimeType: string;
|
|
6
|
+
storagePath?: string;
|
|
7
|
+
storageFormat?: "base64" | "data-url";
|
|
8
|
+
sourceMessageId: string;
|
|
9
|
+
sourceRole: string;
|
|
10
|
+
origin: "user" | "generated" | "tool" | "unknown";
|
|
11
|
+
/** Approximate index within the conversation timeline. */
|
|
12
|
+
turnIndex: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ImageRegistry {
|
|
15
|
+
images: ImageEntry[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Scan messages and build a registry of all images encountered.
|
|
19
|
+
* Each image block gets a stable entry with enough info to reload later.
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildImageRegistry(messages: readonly Message[], startingTurnIndex?: number): ImageRegistry;
|
|
22
|
+
/**
|
|
23
|
+
* Merge a previous registry (from a compact boundary) with newly extracted entries,
|
|
24
|
+
* deduplicating by storagePath when available.
|
|
25
|
+
*/
|
|
26
|
+
export declare function mergeImageRegistries(previous: ImageRegistry, current: ImageRegistry): ImageRegistry;
|
|
27
|
+
/**
|
|
28
|
+
* Extract a previously persisted ImageRegistry from a compact boundary message's metadata.
|
|
29
|
+
*/
|
|
30
|
+
export declare function extractRegistryFromBoundary(messages: readonly Message[]): ImageRegistry | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Build a human-readable listing of available images for the model to reference.
|
|
33
|
+
*/
|
|
34
|
+
export declare function formatImageRegistryForContext(registry: ImageRegistry): string;
|
|
35
|
+
/**
|
|
36
|
+
* Load the raw base64 data for an image entry. Returns undefined if unreadable.
|
|
37
|
+
*/
|
|
38
|
+
export declare function loadImageData(entry: ImageEntry): string | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Resolve an image reference (id like "img_3", label, or storage path) against a registry.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveImageRef(registry: ImageRegistry, ref: string): ImageEntry | undefined;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
/**
|
|
3
|
+
* Scan messages and build a registry of all images encountered.
|
|
4
|
+
* Each image block gets a stable entry with enough info to reload later.
|
|
5
|
+
*/
|
|
6
|
+
export function buildImageRegistry(messages, startingTurnIndex = 0) {
|
|
7
|
+
const images = [];
|
|
8
|
+
let turnIndex = startingTurnIndex;
|
|
9
|
+
for (const message of messages) {
|
|
10
|
+
for (const block of message.blocks) {
|
|
11
|
+
if (block.type !== "image")
|
|
12
|
+
continue;
|
|
13
|
+
images.push({
|
|
14
|
+
id: `img_${images.length + 1}`,
|
|
15
|
+
label: block.label,
|
|
16
|
+
mimeType: block.mimeType,
|
|
17
|
+
storagePath: block.storage?.path,
|
|
18
|
+
storageFormat: block.storage?.format,
|
|
19
|
+
sourceMessageId: message.id,
|
|
20
|
+
sourceRole: message.role,
|
|
21
|
+
origin: inferImageOrigin(message, block),
|
|
22
|
+
turnIndex,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
turnIndex += 1;
|
|
26
|
+
}
|
|
27
|
+
return { images };
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Merge a previous registry (from a compact boundary) with newly extracted entries,
|
|
31
|
+
* deduplicating by storagePath when available.
|
|
32
|
+
*/
|
|
33
|
+
export function mergeImageRegistries(previous, current) {
|
|
34
|
+
const seen = new Set();
|
|
35
|
+
const merged = [];
|
|
36
|
+
for (const entry of previous.images) {
|
|
37
|
+
const key = entry.storagePath ?? `${entry.sourceMessageId}:${entry.label}`;
|
|
38
|
+
if (seen.has(key))
|
|
39
|
+
continue;
|
|
40
|
+
seen.add(key);
|
|
41
|
+
merged.push(entry);
|
|
42
|
+
}
|
|
43
|
+
for (const entry of current.images) {
|
|
44
|
+
const key = entry.storagePath ?? `${entry.sourceMessageId}:${entry.label}`;
|
|
45
|
+
if (seen.has(key))
|
|
46
|
+
continue;
|
|
47
|
+
seen.add(key);
|
|
48
|
+
merged.push({ ...entry, id: `img_${merged.length + 1}` });
|
|
49
|
+
}
|
|
50
|
+
return { images: merged };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extract a previously persisted ImageRegistry from a compact boundary message's metadata.
|
|
54
|
+
*/
|
|
55
|
+
export function extractRegistryFromBoundary(messages) {
|
|
56
|
+
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
57
|
+
const meta = messages[i].metadata;
|
|
58
|
+
if (meta?.compactBoundary && meta.imageRegistry) {
|
|
59
|
+
return meta.imageRegistry;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Build a human-readable listing of available images for the model to reference.
|
|
66
|
+
*/
|
|
67
|
+
export function formatImageRegistryForContext(registry) {
|
|
68
|
+
if (registry.images.length === 0)
|
|
69
|
+
return "";
|
|
70
|
+
const lines = registry.images.map((entry) => {
|
|
71
|
+
const label = entry.label ? `"${entry.label}"` : `unlabeled`;
|
|
72
|
+
const origin = entry.origin !== "unknown" ? ` (${entry.origin})` : "";
|
|
73
|
+
const path = entry.storagePath ? ` [stored: ${entry.storagePath}]` : " [no storage]";
|
|
74
|
+
return `- ${entry.id}: ${label}, ${entry.mimeType}${origin}${path}`;
|
|
75
|
+
});
|
|
76
|
+
return [
|
|
77
|
+
"Available images from conversation history (use load_image tool with the id to examine any image):",
|
|
78
|
+
...lines,
|
|
79
|
+
].join("\n");
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Load the raw base64 data for an image entry. Returns undefined if unreadable.
|
|
83
|
+
*/
|
|
84
|
+
export function loadImageData(entry) {
|
|
85
|
+
if (!entry.storagePath)
|
|
86
|
+
return undefined;
|
|
87
|
+
try {
|
|
88
|
+
return readFileSync(entry.storagePath, "utf8");
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Resolve an image reference (id like "img_3", label, or storage path) against a registry.
|
|
96
|
+
*/
|
|
97
|
+
export function resolveImageRef(registry, ref) {
|
|
98
|
+
const normalized = ref.trim().toLowerCase();
|
|
99
|
+
const byId = registry.images.find((e) => e.id.toLowerCase() === normalized);
|
|
100
|
+
if (byId)
|
|
101
|
+
return byId;
|
|
102
|
+
const numMatch = /^(?:\[?img[_#]?|image\s*)?(\d+)\]?$/i.exec(normalized);
|
|
103
|
+
if (numMatch) {
|
|
104
|
+
const idx = Number(numMatch[1]) - 1;
|
|
105
|
+
if (idx >= 0 && idx < registry.images.length)
|
|
106
|
+
return registry.images[idx];
|
|
107
|
+
}
|
|
108
|
+
const byLabel = registry.images.find((e) => e.label?.toLowerCase() === normalized);
|
|
109
|
+
if (byLabel)
|
|
110
|
+
return byLabel;
|
|
111
|
+
const byPath = registry.images.find((e) => e.storagePath?.toLowerCase() === normalized ||
|
|
112
|
+
e.storagePath?.toLowerCase().endsWith(normalized));
|
|
113
|
+
if (byPath)
|
|
114
|
+
return byPath;
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
function inferImageOrigin(message, _block) {
|
|
118
|
+
if (message.role === "user")
|
|
119
|
+
return "user";
|
|
120
|
+
if (message.metadata?.generatedImages || message.metadata?.tool === "image2")
|
|
121
|
+
return "generated";
|
|
122
|
+
if (message.role === "tool_result")
|
|
123
|
+
return "tool";
|
|
124
|
+
if (message.role === "assistant")
|
|
125
|
+
return "generated";
|
|
126
|
+
return "unknown";
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=image-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-registry.js","sourceRoot":"","sources":["../../src/core/image-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Message } from "../types/messages.js";
|
|
2
|
+
import { type ImageRegistry } from "./image-registry.js";
|
|
2
3
|
export interface ToolResultBudgetOptions {
|
|
3
4
|
maxSerializedLength?: number;
|
|
4
5
|
}
|
|
@@ -8,3 +9,8 @@ export declare function ensureToolResultPairing(messages: readonly Message[]): M
|
|
|
8
9
|
export declare function hasValidToolResultPairing(messages: readonly Message[]): boolean;
|
|
9
10
|
export declare function prependUserContext<T extends object>(messages: readonly Message[], userContext: T): Message[];
|
|
10
11
|
export declare function appendSystemContext<T extends object>(systemPrompt: string, systemContext: T): string;
|
|
12
|
+
/**
|
|
13
|
+
* Build a complete ImageRegistry from the current message set,
|
|
14
|
+
* merging any registry persisted in a compact boundary with images from recent messages.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getImageRegistryFromMessages(messages: readonly Message[]): ImageRegistry;
|