grov 0.5.11 → 0.6.13
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/cli/agents/registry.d.ts +17 -0
- package/dist/cli/agents/registry.js +132 -0
- package/dist/cli/commands/agents.d.ts +1 -0
- package/dist/cli/commands/agents.js +48 -0
- package/dist/cli/commands/disable.d.ts +1 -0
- package/dist/cli/commands/disable.js +179 -0
- package/dist/cli/commands/doctor.d.ts +1 -0
- package/dist/cli/commands/doctor.js +157 -0
- package/dist/{commands → cli/commands}/drift-test.js +39 -26
- package/dist/cli/commands/init.d.ts +1 -0
- package/dist/cli/commands/init.js +90 -0
- package/dist/{commands → cli/commands}/login.js +19 -18
- package/dist/{commands → cli/commands}/logout.js +1 -1
- package/dist/{commands → cli/commands}/proxy-status.js +1 -1
- package/dist/cli/commands/setup.d.ts +6 -0
- package/dist/cli/commands/setup.js +309 -0
- package/dist/{commands → cli/commands}/status.js +1 -1
- package/dist/{commands → cli/commands}/sync.d.ts +1 -0
- package/dist/{commands → cli/commands}/sync.js +59 -4
- package/dist/{commands → cli/commands}/uninstall.js +2 -2
- package/dist/cli/index.js +270 -0
- package/dist/{lib → core/cloud}/cloud-sync.d.ts +3 -3
- package/dist/{lib → core/cloud}/cloud-sync.js +10 -10
- package/dist/{lib → core/extraction}/correction-builder-proxy.d.ts +1 -1
- package/dist/{lib → core/extraction}/correction-builder-proxy.js +0 -4
- package/dist/{lib → core/extraction}/drift-checker-proxy.d.ts +13 -9
- package/dist/core/extraction/drift-checker-proxy.js +510 -0
- package/dist/{lib → core/extraction}/llm-extractor.d.ts +8 -38
- package/dist/{lib → core/extraction}/llm-extractor.js +132 -220
- package/dist/{lib → core}/store/sessions.js +3 -19
- package/dist/core/store/store.d.ts +1 -0
- package/dist/{lib → core/store}/store.js +1 -1
- package/dist/{lib → core}/store/types.d.ts +0 -4
- package/dist/integrations/mcp/cache.d.ts +27 -0
- package/dist/integrations/mcp/cache.js +106 -0
- package/dist/integrations/mcp/capture/antigravity-parser.d.ts +26 -0
- package/dist/integrations/mcp/capture/antigravity-parser.js +272 -0
- package/dist/integrations/mcp/capture/antigravity-scanner.d.ts +24 -0
- package/dist/integrations/mcp/capture/antigravity-scanner.js +153 -0
- package/dist/integrations/mcp/capture/antigravity-sync-tracker.d.ts +29 -0
- package/dist/integrations/mcp/capture/antigravity-sync-tracker.js +115 -0
- package/dist/integrations/mcp/capture/cli-extractor.d.ts +18 -0
- package/dist/integrations/mcp/capture/cli-extractor.js +258 -0
- package/dist/integrations/mcp/capture/cli-synced.d.ts +4 -0
- package/dist/integrations/mcp/capture/cli-synced.js +62 -0
- package/dist/integrations/mcp/capture/cli-transform.d.ts +30 -0
- package/dist/integrations/mcp/capture/cli-transform.js +62 -0
- package/dist/integrations/mcp/capture/cli-watcher.d.ts +31 -0
- package/dist/integrations/mcp/capture/cli-watcher.js +106 -0
- package/dist/integrations/mcp/capture/hook-handler.d.ts +2 -0
- package/dist/integrations/mcp/capture/hook-handler.js +157 -0
- package/dist/integrations/mcp/capture/sqlite-reader.d.ts +35 -0
- package/dist/integrations/mcp/capture/sqlite-reader.js +388 -0
- package/dist/integrations/mcp/capture/sync-tracker.d.ts +16 -0
- package/dist/integrations/mcp/capture/sync-tracker.js +102 -0
- package/dist/integrations/mcp/clients/cursor/rules-installer.d.ts +19 -0
- package/dist/integrations/mcp/clients/cursor/rules-installer.js +123 -0
- package/dist/integrations/mcp/index.d.ts +1 -0
- package/dist/integrations/mcp/index.js +94 -0
- package/dist/integrations/mcp/logger.d.ts +8 -0
- package/dist/integrations/mcp/logger.js +50 -0
- package/dist/integrations/mcp/server.d.ts +5 -0
- package/dist/integrations/mcp/server.js +58 -0
- package/dist/integrations/mcp/tools/expand.d.ts +1 -0
- package/dist/integrations/mcp/tools/expand.js +53 -0
- package/dist/integrations/mcp/tools/preview.d.ts +1 -0
- package/dist/integrations/mcp/tools/preview.js +64 -0
- package/dist/integrations/proxy/agents/base.d.ts +43 -0
- package/dist/integrations/proxy/agents/base.js +13 -0
- package/dist/{proxy/utils → integrations/proxy/agents/claude}/extractors.d.ts +4 -8
- package/dist/{proxy/utils → integrations/proxy/agents/claude}/extractors.js +4 -33
- package/dist/{proxy → integrations/proxy/agents/claude}/forwarder.d.ts +1 -1
- package/dist/{proxy → integrations/proxy/agents/claude}/forwarder.js +22 -6
- package/dist/integrations/proxy/agents/claude/index.d.ts +43 -0
- package/dist/integrations/proxy/agents/claude/index.js +386 -0
- package/dist/{proxy/action-parser.d.ts → integrations/proxy/agents/claude/parser.d.ts} +1 -1
- package/dist/integrations/proxy/agents/codex/extractors.d.ts +6 -0
- package/dist/integrations/proxy/agents/codex/extractors.js +49 -0
- package/dist/integrations/proxy/agents/codex/forwarder.d.ts +9 -0
- package/dist/integrations/proxy/agents/codex/forwarder.js +125 -0
- package/dist/integrations/proxy/agents/codex/index.d.ts +44 -0
- package/dist/integrations/proxy/agents/codex/index.js +371 -0
- package/dist/integrations/proxy/agents/codex/parser.d.ts +11 -0
- package/dist/integrations/proxy/agents/codex/parser.js +104 -0
- package/dist/integrations/proxy/agents/codex/patch.d.ts +12 -0
- package/dist/integrations/proxy/agents/codex/patch.js +40 -0
- package/dist/integrations/proxy/agents/codex/settings.d.ts +18 -0
- package/dist/integrations/proxy/agents/codex/settings.js +73 -0
- package/dist/integrations/proxy/agents/codex/types.d.ts +59 -0
- package/dist/integrations/proxy/agents/codex/types.js +2 -0
- package/dist/integrations/proxy/agents/index.d.ts +11 -0
- package/dist/integrations/proxy/agents/index.js +25 -0
- package/dist/integrations/proxy/agents/types.d.ts +77 -0
- package/dist/integrations/proxy/agents/types.js +2 -0
- package/dist/{proxy → integrations/proxy/cache}/extended-cache.js +2 -6
- package/dist/{proxy → integrations/proxy}/config.js +1 -1
- package/dist/{proxy → integrations/proxy}/handlers/preprocess.d.ts +3 -3
- package/dist/integrations/proxy/handlers/preprocess.js +194 -0
- package/dist/integrations/proxy/index.js +20 -0
- package/dist/integrations/proxy/injection/memory-injection.d.ts +56 -0
- package/dist/integrations/proxy/injection/memory-injection.js +252 -0
- package/dist/integrations/proxy/orchestrator.d.ts +30 -0
- package/dist/integrations/proxy/orchestrator.js +954 -0
- package/dist/integrations/proxy/request-processor.d.ts +14 -0
- package/dist/integrations/proxy/request-processor.js +68 -0
- package/dist/{proxy → integrations/proxy}/response-processor.d.ts +4 -3
- package/dist/{proxy → integrations/proxy}/response-processor.js +51 -43
- package/dist/{proxy → integrations/proxy}/server.d.ts +0 -1
- package/dist/integrations/proxy/server.js +146 -0
- package/dist/{proxy → integrations/proxy}/types.d.ts +4 -0
- package/dist/{proxy → integrations/proxy}/utils/logging.d.ts +1 -0
- package/dist/{proxy → integrations/proxy}/utils/logging.js +5 -0
- package/package.json +31 -10
- package/postinstall.js +62 -6
- package/dist/cli.js +0 -149
- package/dist/commands/capture.d.ts +0 -6
- package/dist/commands/capture.js +0 -324
- package/dist/commands/disable.d.ts +0 -1
- package/dist/commands/disable.js +0 -14
- package/dist/commands/doctor.d.ts +0 -1
- package/dist/commands/doctor.js +0 -89
- package/dist/commands/init.d.ts +0 -1
- package/dist/commands/init.js +0 -52
- package/dist/commands/inject.d.ts +0 -5
- package/dist/commands/inject.js +0 -88
- package/dist/commands/prompt-inject.d.ts +0 -4
- package/dist/commands/prompt-inject.js +0 -451
- package/dist/commands/unregister.d.ts +0 -1
- package/dist/commands/unregister.js +0 -28
- package/dist/lib/anchor-extractor.d.ts +0 -30
- package/dist/lib/anchor-extractor.js +0 -296
- package/dist/lib/correction-builder.d.ts +0 -10
- package/dist/lib/correction-builder.js +0 -226
- package/dist/lib/drift-checker-proxy.js +0 -373
- package/dist/lib/drift-checker.d.ts +0 -66
- package/dist/lib/drift-checker.js +0 -341
- package/dist/lib/hooks.d.ts +0 -38
- package/dist/lib/hooks.js +0 -291
- package/dist/lib/jsonl-parser.d.ts +0 -87
- package/dist/lib/jsonl-parser.js +0 -281
- package/dist/lib/session-parser.d.ts +0 -44
- package/dist/lib/session-parser.js +0 -256
- package/dist/lib/store.d.ts +0 -1
- package/dist/proxy/cache.d.ts +0 -32
- package/dist/proxy/cache.js +0 -47
- package/dist/proxy/handlers/preprocess.js +0 -186
- package/dist/proxy/index.js +0 -30
- package/dist/proxy/injection/delta-tracking.d.ts +0 -11
- package/dist/proxy/injection/delta-tracking.js +0 -94
- package/dist/proxy/injection/injectors.d.ts +0 -7
- package/dist/proxy/injection/injectors.js +0 -139
- package/dist/proxy/request-processor.d.ts +0 -27
- package/dist/proxy/request-processor.js +0 -233
- package/dist/proxy/server.js +0 -1289
- /package/dist/{commands → cli/commands}/drift-test.d.ts +0 -0
- /package/dist/{commands → cli/commands}/login.d.ts +0 -0
- /package/dist/{commands → cli/commands}/logout.d.ts +0 -0
- /package/dist/{commands → cli/commands}/proxy-status.d.ts +0 -0
- /package/dist/{commands → cli/commands}/status.d.ts +0 -0
- /package/dist/{commands → cli/commands}/uninstall.d.ts +0 -0
- /package/dist/{cli.d.ts → cli/index.d.ts} +0 -0
- /package/dist/{lib → core/cloud}/api-client.d.ts +0 -0
- /package/dist/{lib → core/cloud}/api-client.js +0 -0
- /package/dist/{lib → core/cloud}/credentials.d.ts +0 -0
- /package/dist/{lib → core/cloud}/credentials.js +0 -0
- /package/dist/{lib → core}/store/convenience.d.ts +0 -0
- /package/dist/{lib → core}/store/convenience.js +0 -0
- /package/dist/{lib → core}/store/database.d.ts +0 -0
- /package/dist/{lib → core}/store/database.js +0 -0
- /package/dist/{lib → core}/store/drift.d.ts +0 -0
- /package/dist/{lib → core}/store/drift.js +0 -0
- /package/dist/{lib → core}/store/index.d.ts +0 -0
- /package/dist/{lib → core}/store/index.js +0 -0
- /package/dist/{lib → core}/store/sessions.d.ts +0 -0
- /package/dist/{lib → core}/store/steps.d.ts +0 -0
- /package/dist/{lib → core}/store/steps.js +0 -0
- /package/dist/{lib → core}/store/tasks.d.ts +0 -0
- /package/dist/{lib → core}/store/tasks.js +0 -0
- /package/dist/{lib → core}/store/types.js +0 -0
- /package/dist/{proxy/action-parser.js → integrations/proxy/agents/claude/parser.js} +0 -0
- /package/dist/{lib → integrations/proxy/agents/claude}/settings.d.ts +0 -0
- /package/dist/{lib → integrations/proxy/agents/claude}/settings.js +0 -0
- /package/dist/{proxy → integrations/proxy/cache}/extended-cache.d.ts +0 -0
- /package/dist/{proxy → integrations/proxy}/config.d.ts +0 -0
- /package/dist/{proxy → integrations/proxy}/index.d.ts +0 -0
- /package/dist/{proxy → integrations/proxy}/types.js +0 -0
- /package/dist/{lib → utils}/debug.d.ts +0 -0
- /package/dist/{lib → utils}/debug.js +0 -0
- /package/dist/{lib → utils}/utils.d.ts +0 -0
- /package/dist/{lib → utils}/utils.js +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Parse Codex apply_patch format to extract file operations
|
|
2
|
+
const ADD_FILE_PREFIX = '*** Add File: ';
|
|
3
|
+
const UPDATE_FILE_PREFIX = '*** Update File: ';
|
|
4
|
+
const DELETE_FILE_PREFIX = '*** Delete File: ';
|
|
5
|
+
const MOVE_TO_PREFIX = '*** Move to: ';
|
|
6
|
+
export function parsePatchContent(patchText) {
|
|
7
|
+
const files = [];
|
|
8
|
+
const operations = [];
|
|
9
|
+
let hasAdd = false;
|
|
10
|
+
let hasDelete = false;
|
|
11
|
+
let currentOp = null;
|
|
12
|
+
for (const line of patchText.split('\n')) {
|
|
13
|
+
if (line.startsWith(ADD_FILE_PREFIX)) {
|
|
14
|
+
const file = line.slice(ADD_FILE_PREFIX.length).trim();
|
|
15
|
+
files.push(file);
|
|
16
|
+
hasAdd = true;
|
|
17
|
+
currentOp = { type: 'add', file };
|
|
18
|
+
operations.push(currentOp);
|
|
19
|
+
}
|
|
20
|
+
else if (line.startsWith(UPDATE_FILE_PREFIX)) {
|
|
21
|
+
const file = line.slice(UPDATE_FILE_PREFIX.length).trim();
|
|
22
|
+
files.push(file);
|
|
23
|
+
currentOp = { type: 'update', file };
|
|
24
|
+
operations.push(currentOp);
|
|
25
|
+
}
|
|
26
|
+
else if (line.startsWith(DELETE_FILE_PREFIX)) {
|
|
27
|
+
const file = line.slice(DELETE_FILE_PREFIX.length).trim();
|
|
28
|
+
files.push(file);
|
|
29
|
+
hasDelete = true;
|
|
30
|
+
currentOp = { type: 'delete', file };
|
|
31
|
+
operations.push(currentOp);
|
|
32
|
+
}
|
|
33
|
+
else if (line.startsWith(MOVE_TO_PREFIX) && currentOp) {
|
|
34
|
+
const moveTo = line.slice(MOVE_TO_PREFIX.length).trim();
|
|
35
|
+
currentOp.moveTo = moveTo;
|
|
36
|
+
files.push(moveTo);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return { files: [...new Set(files)], operations, hasAdd, hasDelete };
|
|
40
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface ModelProvider {
|
|
2
|
+
name: string;
|
|
3
|
+
base_url: string;
|
|
4
|
+
env_key: string;
|
|
5
|
+
wire_api: 'responses' | 'chat';
|
|
6
|
+
query_params?: Record<string, string>;
|
|
7
|
+
http_headers?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
interface CodexConfig {
|
|
10
|
+
model_providers?: Record<string, ModelProvider>;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
export declare function getSettingsPath(): string;
|
|
14
|
+
export declare function readCodexConfig(): CodexConfig;
|
|
15
|
+
export declare function setProxyEnv(enable: boolean): {
|
|
16
|
+
action: 'added' | 'removed' | 'unchanged';
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Codex CLI settings management (~/.codex/config.toml)
|
|
2
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { parse, stringify } from 'smol-toml';
|
|
6
|
+
const CODEX_DIR = join(homedir(), '.codex');
|
|
7
|
+
const CONFIG_PATH = join(CODEX_DIR, 'config.toml');
|
|
8
|
+
const PROXY_URL = 'http://127.0.0.1:8080/v1';
|
|
9
|
+
export function getSettingsPath() {
|
|
10
|
+
return CONFIG_PATH;
|
|
11
|
+
}
|
|
12
|
+
export function readCodexConfig() {
|
|
13
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
14
|
+
return {};
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
const content = readFileSync(CONFIG_PATH, 'utf-8');
|
|
18
|
+
return parse(content);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function writeCodexConfig(config) {
|
|
25
|
+
if (!existsSync(CODEX_DIR)) {
|
|
26
|
+
mkdirSync(CODEX_DIR, { recursive: true, mode: 0o700 });
|
|
27
|
+
}
|
|
28
|
+
writeFileSync(CONFIG_PATH, stringify(config), { mode: 0o600 });
|
|
29
|
+
}
|
|
30
|
+
export function setProxyEnv(enable) {
|
|
31
|
+
const config = readCodexConfig();
|
|
32
|
+
if (enable) {
|
|
33
|
+
if (!config.model_providers) {
|
|
34
|
+
config.model_providers = {};
|
|
35
|
+
}
|
|
36
|
+
const alreadyConfigured = config.model_providers.grov?.base_url === PROXY_URL &&
|
|
37
|
+
config.model_provider === 'grov';
|
|
38
|
+
if (alreadyConfigured) {
|
|
39
|
+
return { action: 'unchanged' };
|
|
40
|
+
}
|
|
41
|
+
// Store original provider to restore on disable
|
|
42
|
+
if (config.model_provider && config.model_provider !== 'grov') {
|
|
43
|
+
config._grov_original_provider = config.model_provider;
|
|
44
|
+
}
|
|
45
|
+
config.model_providers.grov = {
|
|
46
|
+
name: 'Grov Memory Proxy',
|
|
47
|
+
base_url: PROXY_URL,
|
|
48
|
+
env_key: 'OPENAI_API_KEY',
|
|
49
|
+
wire_api: 'responses',
|
|
50
|
+
};
|
|
51
|
+
// Tell Codex to use the grov provider
|
|
52
|
+
config.model_provider = 'grov';
|
|
53
|
+
writeCodexConfig(config);
|
|
54
|
+
return { action: 'added' };
|
|
55
|
+
}
|
|
56
|
+
if (!config.model_providers?.grov) {
|
|
57
|
+
return { action: 'unchanged' };
|
|
58
|
+
}
|
|
59
|
+
delete config.model_providers.grov;
|
|
60
|
+
// Restore original provider or remove the setting
|
|
61
|
+
if (config._grov_original_provider) {
|
|
62
|
+
config.model_provider = config._grov_original_provider;
|
|
63
|
+
delete config._grov_original_provider;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
delete config.model_provider;
|
|
67
|
+
}
|
|
68
|
+
if (Object.keys(config.model_providers).length === 0) {
|
|
69
|
+
delete config.model_providers;
|
|
70
|
+
}
|
|
71
|
+
writeCodexConfig(config);
|
|
72
|
+
return { action: 'removed' };
|
|
73
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export interface CodexRequestBody {
|
|
2
|
+
model: string;
|
|
3
|
+
instructions?: string;
|
|
4
|
+
input: CodexInputItem[];
|
|
5
|
+
previous_response_id?: string;
|
|
6
|
+
stream?: boolean;
|
|
7
|
+
tools?: CodexTool[];
|
|
8
|
+
parallel_tool_calls?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export type CodexInputItem = {
|
|
11
|
+
role: 'user' | 'assistant';
|
|
12
|
+
content: string | Array<{
|
|
13
|
+
type: string;
|
|
14
|
+
text?: string;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}>;
|
|
17
|
+
} | {
|
|
18
|
+
type: 'function_call_output';
|
|
19
|
+
call_id: string;
|
|
20
|
+
output: string;
|
|
21
|
+
};
|
|
22
|
+
export interface CodexTool {
|
|
23
|
+
type: 'function';
|
|
24
|
+
function: {
|
|
25
|
+
name: string;
|
|
26
|
+
description?: string;
|
|
27
|
+
parameters?: Record<string, unknown>;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export interface CodexResponse {
|
|
31
|
+
id: string;
|
|
32
|
+
status: 'completed' | 'failed' | 'in_progress';
|
|
33
|
+
output: CodexOutputItem[];
|
|
34
|
+
usage?: {
|
|
35
|
+
input_tokens: number;
|
|
36
|
+
output_tokens: number;
|
|
37
|
+
total_tokens?: number;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export type CodexOutputItem = {
|
|
41
|
+
type: 'message';
|
|
42
|
+
role: 'assistant';
|
|
43
|
+
content: CodexMessageContent[];
|
|
44
|
+
} | CodexFunctionCall;
|
|
45
|
+
export interface CodexMessageContent {
|
|
46
|
+
type: 'output_text';
|
|
47
|
+
text: string;
|
|
48
|
+
}
|
|
49
|
+
export interface CodexFunctionCall {
|
|
50
|
+
type: 'function_call';
|
|
51
|
+
call_id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
arguments: string;
|
|
54
|
+
}
|
|
55
|
+
export interface ShellArguments {
|
|
56
|
+
command: string[];
|
|
57
|
+
workdir: string;
|
|
58
|
+
timeout?: number;
|
|
59
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FastifyRequest } from 'fastify';
|
|
2
|
+
import type { AgentAdapter, AgentName } from './types.js';
|
|
3
|
+
export declare function getAllAgents(): AgentAdapter[];
|
|
4
|
+
export declare function getAgentForRequest(request: FastifyRequest): AgentAdapter | undefined;
|
|
5
|
+
export declare function getAgentByName(name: AgentName): AgentAdapter | undefined;
|
|
6
|
+
export declare function getAgentByEndpoint(endpoint: string): AgentAdapter | undefined;
|
|
7
|
+
export declare function getSupportedEndpoints(): string[];
|
|
8
|
+
export { ClaudeAdapter } from './claude/index.js';
|
|
9
|
+
export { CodexAdapter } from './codex/index.js';
|
|
10
|
+
export { BaseAdapter } from './base.js';
|
|
11
|
+
export type { AgentAdapter, AgentName, AgentSettings, NormalizedAction, ForwardResult, TokenUsage, ToolUseBlock, } from './types.js';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Agent registry - detects and provides agent adapters
|
|
2
|
+
import { ClaudeAdapter } from './claude/index.js';
|
|
3
|
+
import { CodexAdapter } from './codex/index.js';
|
|
4
|
+
const adapters = [
|
|
5
|
+
new ClaudeAdapter(),
|
|
6
|
+
new CodexAdapter(),
|
|
7
|
+
];
|
|
8
|
+
export function getAllAgents() {
|
|
9
|
+
return adapters;
|
|
10
|
+
}
|
|
11
|
+
export function getAgentForRequest(request) {
|
|
12
|
+
return adapters.find(adapter => adapter.canHandle(request));
|
|
13
|
+
}
|
|
14
|
+
export function getAgentByName(name) {
|
|
15
|
+
return adapters.find(adapter => adapter.name === name);
|
|
16
|
+
}
|
|
17
|
+
export function getAgentByEndpoint(endpoint) {
|
|
18
|
+
return adapters.find(adapter => adapter.endpoint === endpoint);
|
|
19
|
+
}
|
|
20
|
+
export function getSupportedEndpoints() {
|
|
21
|
+
return adapters.map(adapter => adapter.endpoint);
|
|
22
|
+
}
|
|
23
|
+
export { ClaudeAdapter } from './claude/index.js';
|
|
24
|
+
export { CodexAdapter } from './codex/index.js';
|
|
25
|
+
export { BaseAdapter } from './base.js';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { FastifyRequest } from 'fastify';
|
|
2
|
+
import type { StepActionType } from '../../../core/store/store.js';
|
|
3
|
+
import type { ConversationMessage } from '../../../core/extraction/llm-extractor.js';
|
|
4
|
+
export type AgentName = 'claude' | 'codex' | 'gemini';
|
|
5
|
+
export interface NormalizedAction {
|
|
6
|
+
toolName: string;
|
|
7
|
+
actionType: StepActionType;
|
|
8
|
+
sourceAgent: AgentName;
|
|
9
|
+
files: string[];
|
|
10
|
+
folders: string[];
|
|
11
|
+
command?: string;
|
|
12
|
+
rawInput: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface ForwardResult {
|
|
15
|
+
statusCode: number;
|
|
16
|
+
headers: Record<string, string>;
|
|
17
|
+
body: unknown;
|
|
18
|
+
rawBody: string;
|
|
19
|
+
wasSSE?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface TokenUsage {
|
|
22
|
+
inputTokens: number;
|
|
23
|
+
outputTokens: number;
|
|
24
|
+
totalTokens: number;
|
|
25
|
+
cacheCreation: number;
|
|
26
|
+
cacheRead: number;
|
|
27
|
+
}
|
|
28
|
+
export interface ToolUseBlock {
|
|
29
|
+
id: string;
|
|
30
|
+
name: string;
|
|
31
|
+
input: unknown;
|
|
32
|
+
}
|
|
33
|
+
export interface AgentSettings {
|
|
34
|
+
getConfigPath(): string;
|
|
35
|
+
setProxyEnabled(enabled: boolean): {
|
|
36
|
+
action: 'added' | 'removed' | 'unchanged';
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export interface AgentAdapter {
|
|
40
|
+
readonly name: AgentName;
|
|
41
|
+
readonly endpoint: string;
|
|
42
|
+
canHandle(request: FastifyRequest): boolean;
|
|
43
|
+
forward(body: unknown, headers: Record<string, string>, rawBody?: Buffer): Promise<ForwardResult>;
|
|
44
|
+
extractProjectPath(body: unknown): string | null;
|
|
45
|
+
extractSessionId(response: unknown): string | null;
|
|
46
|
+
extractTextContent(response: unknown): string;
|
|
47
|
+
extractGoal(messages: unknown[]): string;
|
|
48
|
+
extractHistory(messages: unknown[]): ConversationMessage[];
|
|
49
|
+
extractUsage(response: unknown): TokenUsage;
|
|
50
|
+
isValidResponse(body: unknown): boolean;
|
|
51
|
+
isSubagentModel(model: string): boolean;
|
|
52
|
+
isEndTurn(response: unknown): boolean;
|
|
53
|
+
isToolUse(response: unknown): boolean;
|
|
54
|
+
parseActions(response: unknown): NormalizedAction[];
|
|
55
|
+
getToolUseBlocks(response: unknown): ToolUseBlock[];
|
|
56
|
+
findInternalToolUse(response: unknown, toolName: string): ToolUseBlock | null;
|
|
57
|
+
injectMemory(body: unknown, memory: string): unknown;
|
|
58
|
+
injectDelta(body: unknown, delta: string): unknown;
|
|
59
|
+
injectTool(body: unknown, toolDef: unknown): unknown;
|
|
60
|
+
buildGrovExpandTool(): unknown;
|
|
61
|
+
getMessages(body: unknown): unknown[];
|
|
62
|
+
setMessages(body: unknown, messages: unknown[]): unknown;
|
|
63
|
+
getLastUserContent(body: unknown): string;
|
|
64
|
+
injectIntoRawSystemPrompt(rawBody: string, injection: string): {
|
|
65
|
+
modified: string;
|
|
66
|
+
success: boolean;
|
|
67
|
+
};
|
|
68
|
+
injectIntoRawUserMessage(rawBody: string, injection: string): string;
|
|
69
|
+
injectToolIntoRawBody(rawBody: string, toolDef: unknown): {
|
|
70
|
+
modified: string;
|
|
71
|
+
success: boolean;
|
|
72
|
+
};
|
|
73
|
+
filterResponseHeaders(headers: Record<string, string | string[]>): Record<string, string>;
|
|
74
|
+
buildContinueBody(body: unknown, assistantContent: unknown, toolResult: string, toolId: string): unknown;
|
|
75
|
+
getResponseContentType(wasSSE: boolean): string;
|
|
76
|
+
getSettings(): AgentSettings;
|
|
77
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Extended Cache - Keep Anthropic cache alive during idle
|
|
2
2
|
// Sends minimal keep-alive requests to prevent cache TTL expiration
|
|
3
|
-
import { forwardToAnthropic } from '
|
|
3
|
+
import { forwardToAnthropic, isForwardError } from '../agents/claude/forwarder.js';
|
|
4
4
|
export const extendedCache = new Map();
|
|
5
5
|
// Timing constants
|
|
6
6
|
const EXTENDED_CACHE_IDLE_THRESHOLD = 4 * 60 * 1000; // 4 minutes (under 5-min TTL)
|
|
@@ -94,10 +94,6 @@ async function sendExtendedCacheKeepAlive(projectPath, entry) {
|
|
|
94
94
|
if (result.statusCode !== 200) {
|
|
95
95
|
throw new Error(`Keep-alive failed: ${result.statusCode}`);
|
|
96
96
|
}
|
|
97
|
-
// Log cache metrics (minimal)
|
|
98
|
-
const usage = result.body.usage;
|
|
99
|
-
const cacheRead = usage?.cache_read_input_tokens || 0;
|
|
100
|
-
console.log(`[CACHE] keep-alive ${projectName}: read=${cacheRead}`);
|
|
101
97
|
}
|
|
102
98
|
export async function checkExtendedCache() {
|
|
103
99
|
const now = Date.now();
|
|
@@ -133,7 +129,7 @@ export async function checkExtendedCache() {
|
|
|
133
129
|
})
|
|
134
130
|
.catch((err) => {
|
|
135
131
|
extendedCache.delete(projectPath);
|
|
136
|
-
const errMsg = err instanceof Error ? err.message : 'unknown';
|
|
132
|
+
const errMsg = isForwardError(err) ? err.message : (err instanceof Error ? err.message : 'unknown');
|
|
137
133
|
console.error(`[CACHE] keep-alive ${projectName} failed: ${errMsg}`);
|
|
138
134
|
});
|
|
139
135
|
keepAlivePromises.push(promise);
|
|
@@ -9,7 +9,7 @@ export const config = {
|
|
|
9
9
|
REQUEST_TIMEOUT: parseInt(process.env.REQUEST_TIMEOUT || '300000', 10), // 5 minutes
|
|
10
10
|
BODY_LIMIT: parseInt(process.env.BODY_LIMIT || '10485760', 10), // 10MB
|
|
11
11
|
// Drift settings
|
|
12
|
-
DRIFT_CHECK_INTERVAL: parseInt(process.env.DRIFT_CHECK_INTERVAL || '
|
|
12
|
+
DRIFT_CHECK_INTERVAL: parseInt(process.env.DRIFT_CHECK_INTERVAL || '5', 10),
|
|
13
13
|
TOKEN_WARNING_THRESHOLD: parseInt(process.env.TOKEN_WARNING_THRESHOLD || '160000', 10), // 80%
|
|
14
14
|
TOKEN_CLEAR_THRESHOLD: parseInt(process.env.TOKEN_CLEAR_THRESHOLD || '180000', 10), // 90%
|
|
15
15
|
// Security (Phase 2 - disabled for local)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AgentAdapter } from '../agents/types.js';
|
|
2
2
|
export declare function getPendingPlanClear(): {
|
|
3
3
|
projectPath: string;
|
|
4
4
|
summary: string;
|
|
@@ -8,7 +8,7 @@ export declare function setPendingPlanClear(value: {
|
|
|
8
8
|
summary: string;
|
|
9
9
|
}): void;
|
|
10
10
|
export declare function clearPendingPlan(): void;
|
|
11
|
-
export declare function preProcessRequest(body:
|
|
11
|
+
export declare function preProcessRequest(adapter: AgentAdapter, body: unknown, sessionInfo: {
|
|
12
12
|
sessionId: string;
|
|
13
13
|
promptCount: number;
|
|
14
14
|
projectPath: string;
|
|
@@ -17,4 +17,4 @@ export declare function preProcessRequest(body: MessagesRequestBody, sessionInfo
|
|
|
17
17
|
}, detectRequestType: (messages: Array<{
|
|
18
18
|
role: string;
|
|
19
19
|
content: unknown;
|
|
20
|
-
}>, projectPath: string) => 'first' | 'continuation' | 'retry'): Promise<
|
|
20
|
+
}>, projectPath: string) => 'first' | 'continuation' | 'retry'): Promise<unknown>;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
// Pre-process requests before forwarding to upstream API (agent-agnostic)
|
|
2
|
+
import { config } from '../config.js';
|
|
3
|
+
import { extractFilesFromMessages } from '../request-processor.js';
|
|
4
|
+
import { fetchTeamMemories } from '../../../core/cloud/api-client.js';
|
|
5
|
+
import { getSessionState, updateSessionState, markCleared, } from '../../../core/store/store.js';
|
|
6
|
+
import { isSyncEnabled, getSyncTeamId } from '../../../core/cloud/cloud-sync.js';
|
|
7
|
+
import { clearSessionState, cacheMemories, buildMemoryPreview, buildToolDescription, buildDriftRecoveryInjection, reconstructMessages, addInjectionRecord, commitPendingRecords, setCachedPreview, getCachedPreview, } from '../injection/memory-injection.js';
|
|
8
|
+
let pendingPlanClear = null;
|
|
9
|
+
export function getPendingPlanClear() {
|
|
10
|
+
return pendingPlanClear;
|
|
11
|
+
}
|
|
12
|
+
export function setPendingPlanClear(value) {
|
|
13
|
+
pendingPlanClear = value;
|
|
14
|
+
}
|
|
15
|
+
export function clearPendingPlan() {
|
|
16
|
+
pendingPlanClear = null;
|
|
17
|
+
}
|
|
18
|
+
export async function preProcessRequest(adapter, body, sessionInfo, logger, detectRequestType) {
|
|
19
|
+
let modified = { ...body };
|
|
20
|
+
// === WARMUP CHECK (FIRST - before any injection) ===
|
|
21
|
+
// Skip warmup requests entirely - no tool, no system prompt, nothing
|
|
22
|
+
const rawEarlyPrompt = adapter.getLastUserContent(modified);
|
|
23
|
+
const earlyUserPrompt = rawEarlyPrompt
|
|
24
|
+
.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, '')
|
|
25
|
+
.replace(/\\n["']?\s*<\/system-reminder>/g, '')
|
|
26
|
+
.replace(/<\/system-reminder>/g, '')
|
|
27
|
+
.trim();
|
|
28
|
+
if (earlyUserPrompt.startsWith('Warmup')) {
|
|
29
|
+
return modified;
|
|
30
|
+
}
|
|
31
|
+
// Save clean user prompt BEFORE any reconstruction/injection (agent-agnostic)
|
|
32
|
+
modified.__grovRawUserPrompt = earlyUserPrompt.substring(0, 500);
|
|
33
|
+
// === TOOL INJECTION (only for real user requests) ===
|
|
34
|
+
const toolDesc = buildToolDescription();
|
|
35
|
+
modified.__grovInjection = toolDesc;
|
|
36
|
+
modified.__grovInjectionCached = false;
|
|
37
|
+
// Add grov_expand tool to tools array (agent-specific format)
|
|
38
|
+
const toolDef = adapter.buildGrovExpandTool();
|
|
39
|
+
modified = adapter.injectTool(modified, toolDef);
|
|
40
|
+
const messages = adapter.getMessages(modified);
|
|
41
|
+
const requestType = detectRequestType(messages, sessionInfo.projectPath);
|
|
42
|
+
const sessionState = getSessionState(sessionInfo.sessionId);
|
|
43
|
+
// === COMMIT PENDING RECORDS FROM PREVIOUS TURN ===
|
|
44
|
+
// When a new turn starts, commit any pending records so reconstruction stays consistent
|
|
45
|
+
if (requestType === 'first') {
|
|
46
|
+
commitPendingRecords(sessionInfo.projectPath);
|
|
47
|
+
}
|
|
48
|
+
// === PLANNING CLEAR ===
|
|
49
|
+
if (pendingPlanClear && pendingPlanClear.projectPath === sessionInfo.projectPath) {
|
|
50
|
+
modified = adapter.setMessages(modified, []);
|
|
51
|
+
modified = adapter.injectMemory(modified, pendingPlanClear.summary);
|
|
52
|
+
pendingPlanClear = null;
|
|
53
|
+
clearSessionState(sessionInfo.projectPath);
|
|
54
|
+
return modified;
|
|
55
|
+
}
|
|
56
|
+
// === CLEAR MODE (token threshold) ===
|
|
57
|
+
if (sessionState) {
|
|
58
|
+
const currentTokenCount = sessionState.token_count || 0;
|
|
59
|
+
if (currentTokenCount > config.TOKEN_CLEAR_THRESHOLD && sessionState.pending_clear_summary) {
|
|
60
|
+
logger.info({
|
|
61
|
+
msg: 'CLEAR MODE ACTIVATED',
|
|
62
|
+
tokenCount: currentTokenCount,
|
|
63
|
+
threshold: config.TOKEN_CLEAR_THRESHOLD,
|
|
64
|
+
});
|
|
65
|
+
modified = adapter.setMessages(modified, []);
|
|
66
|
+
modified = adapter.injectMemory(modified, sessionState.pending_clear_summary);
|
|
67
|
+
markCleared(sessionInfo.sessionId);
|
|
68
|
+
updateSessionState(sessionInfo.sessionId, { pending_clear_summary: undefined });
|
|
69
|
+
clearSessionState(sessionInfo.projectPath);
|
|
70
|
+
return modified;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Capture original position BEFORE reconstruction (for injection tracking)
|
|
74
|
+
const originalMessages = adapter.getMessages(modified);
|
|
75
|
+
let originalLastUserPos = originalMessages.length - 1;
|
|
76
|
+
for (let i = originalMessages.length - 1; i >= 0; i--) {
|
|
77
|
+
if (originalMessages[i]?.role === 'user') {
|
|
78
|
+
originalLastUserPos = i;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// === RECONSTRUCT HISTORICAL INJECTIONS (for cache consistency) ===
|
|
83
|
+
const currentMessages = adapter.getMessages(modified);
|
|
84
|
+
const { messages: reconstructedMsgs, reconstructedCount } = reconstructMessages(currentMessages, sessionInfo.projectPath);
|
|
85
|
+
if (reconstructedCount > 0) {
|
|
86
|
+
modified = adapter.setMessages(modified, reconstructedMsgs);
|
|
87
|
+
modified.__grovReconstructedCount = reconstructedCount;
|
|
88
|
+
}
|
|
89
|
+
// Pass original position to orchestrator for tool_cycle tracking
|
|
90
|
+
modified.__grovOriginalLastUserPos = originalLastUserPos;
|
|
91
|
+
// === MEMORY PREVIEW INJECTION (new system) ===
|
|
92
|
+
if (requestType === 'first') {
|
|
93
|
+
const teamId = getSyncTeamId();
|
|
94
|
+
const rawUserPrompt = adapter.getLastUserContent(modified);
|
|
95
|
+
// Clean user prompt - strip Claude Code injections that pollute semantic search
|
|
96
|
+
const userPrompt = rawUserPrompt
|
|
97
|
+
.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, '')
|
|
98
|
+
.replace(/\\n["']?\s*<\/system-reminder>/g, '')
|
|
99
|
+
.replace(/<\/system-reminder>/g, '')
|
|
100
|
+
.replace(/^This session is being continued from a previous conversation[\s\S]*?Summary:/gi, '')
|
|
101
|
+
.replace(/^[\s\n"'\\]+/, '')
|
|
102
|
+
.trim();
|
|
103
|
+
const messagesForFiles = adapter.getMessages(modified);
|
|
104
|
+
const mentionedFiles = extractFilesFromMessages(messagesForFiles);
|
|
105
|
+
const syncEnabled = isSyncEnabled();
|
|
106
|
+
if (syncEnabled && teamId && userPrompt) {
|
|
107
|
+
try {
|
|
108
|
+
const memories = await fetchTeamMemories(teamId, sessionInfo.projectPath, {
|
|
109
|
+
status: 'complete',
|
|
110
|
+
limit: 3,
|
|
111
|
+
context: userPrompt,
|
|
112
|
+
current_files: mentionedFiles.length > 0 ? mentionedFiles : undefined,
|
|
113
|
+
});
|
|
114
|
+
if (memories.length > 0) {
|
|
115
|
+
const memoryIds = memories.map(m => m.id.substring(0, 8)).join(', ');
|
|
116
|
+
console.log(`[MEMORY] ${memories.length} memories found: [${memoryIds}]`);
|
|
117
|
+
// Cache for expand tool
|
|
118
|
+
cacheMemories(sessionInfo.projectPath, memories);
|
|
119
|
+
// Build preview for user message
|
|
120
|
+
const preview = buildMemoryPreview(memories);
|
|
121
|
+
// Build drift/recovery if pending
|
|
122
|
+
const driftRecovery = buildDriftRecoveryInjection(sessionState?.pending_correction, sessionState?.pending_forced_recovery);
|
|
123
|
+
// Combine preview + drift/recovery
|
|
124
|
+
let userMsgInjection = preview || '';
|
|
125
|
+
if (driftRecovery) {
|
|
126
|
+
userMsgInjection = userMsgInjection ? `${userMsgInjection}\n${driftRecovery}` : driftRecovery;
|
|
127
|
+
}
|
|
128
|
+
if (userMsgInjection) {
|
|
129
|
+
modified.__grovUserMsgInjection = userMsgInjection;
|
|
130
|
+
setCachedPreview(sessionInfo.projectPath, userMsgInjection, messages.length);
|
|
131
|
+
// Track for reconstruction on next request (use ORIGINAL position)
|
|
132
|
+
addInjectionRecord(sessionInfo.projectPath, {
|
|
133
|
+
position: originalLastUserPos,
|
|
134
|
+
type: 'preview',
|
|
135
|
+
preview: userMsgInjection,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
logger.info({
|
|
139
|
+
msg: 'Memory preview injected',
|
|
140
|
+
memoriesCount: memories.length,
|
|
141
|
+
previewSize: preview?.length || 0,
|
|
142
|
+
hasDriftRecovery: !!driftRecovery,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
// No memories found - inject explicit "no entries" so Claude doesn't use old previews
|
|
147
|
+
let noMemoriesMsg = '[PROJECT KNOWLEDGE BASE: No relevant entries for this query]';
|
|
148
|
+
const driftRecovery = buildDriftRecoveryInjection(sessionState?.pending_correction, sessionState?.pending_forced_recovery);
|
|
149
|
+
if (driftRecovery) {
|
|
150
|
+
noMemoriesMsg = `${noMemoriesMsg}\n${driftRecovery}`;
|
|
151
|
+
}
|
|
152
|
+
modified.__grovUserMsgInjection = noMemoriesMsg;
|
|
153
|
+
setCachedPreview(sessionInfo.projectPath, noMemoriesMsg, messages.length);
|
|
154
|
+
// Track for reconstruction
|
|
155
|
+
addInjectionRecord(sessionInfo.projectPath, {
|
|
156
|
+
position: originalLastUserPos,
|
|
157
|
+
type: 'preview',
|
|
158
|
+
preview: noMemoriesMsg,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// Clear pending corrections after injection
|
|
162
|
+
if (sessionState?.pending_correction || sessionState?.pending_forced_recovery) {
|
|
163
|
+
updateSessionState(sessionInfo.sessionId, {
|
|
164
|
+
pending_correction: undefined,
|
|
165
|
+
pending_forced_recovery: undefined,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
console.error(`[MEMORY] fetchTeamMemories error: ${err}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// Sync not enabled - only inject drift/recovery if pending
|
|
175
|
+
const driftRecovery = buildDriftRecoveryInjection(sessionState?.pending_correction, sessionState?.pending_forced_recovery);
|
|
176
|
+
if (driftRecovery) {
|
|
177
|
+
modified.__grovUserMsgInjection = driftRecovery;
|
|
178
|
+
if (sessionState?.pending_correction || sessionState?.pending_forced_recovery) {
|
|
179
|
+
updateSessionState(sessionInfo.sessionId, {
|
|
180
|
+
pending_correction: undefined,
|
|
181
|
+
pending_forced_recovery: undefined,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else if (requestType === 'retry') {
|
|
188
|
+
const cached = getCachedPreview(sessionInfo.projectPath, messages.length);
|
|
189
|
+
if (cached) {
|
|
190
|
+
modified.__grovUserMsgInjection = cached;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return modified;
|
|
194
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Grov Proxy CLI entry point
|
|
2
|
+
// Load .env file for API keys
|
|
3
|
+
import { config } from 'dotenv';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { homedir } from 'os';
|
|
6
|
+
import { existsSync } from 'fs';
|
|
7
|
+
// Load from current directory .env first
|
|
8
|
+
config();
|
|
9
|
+
// Also load ~/.grov/.env as fallback
|
|
10
|
+
const grovEnvPath = join(homedir(), '.grov', '.env');
|
|
11
|
+
if (existsSync(grovEnvPath)) {
|
|
12
|
+
config({ path: grovEnvPath });
|
|
13
|
+
}
|
|
14
|
+
import { startServer } from './server.js';
|
|
15
|
+
// Note: Claude Code auth comes from request headers (no env var needed)
|
|
16
|
+
// Env loading above is for Codex future use and CLI tools
|
|
17
|
+
startServer().catch((err) => {
|
|
18
|
+
console.error('Proxy failed:', err);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Memory } from '@grov/shared';
|
|
2
|
+
export interface InjectionRecord {
|
|
3
|
+
position: number;
|
|
4
|
+
type: 'preview' | 'tool_cycle';
|
|
5
|
+
preview?: string;
|
|
6
|
+
toolUse?: {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
input: unknown;
|
|
10
|
+
};
|
|
11
|
+
toolResult?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SessionInjectionState {
|
|
14
|
+
memoriesById: Map<string, Memory>;
|
|
15
|
+
injectionHistory: InjectionRecord[];
|
|
16
|
+
pendingRecords: InjectionRecord[];
|
|
17
|
+
lastOriginalMsgCount: number;
|
|
18
|
+
cachedPreview?: {
|
|
19
|
+
preview: string;
|
|
20
|
+
msgCount: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export declare function getOrCreateState(sessionId: string): SessionInjectionState;
|
|
24
|
+
export declare function clearSessionState(sessionId: string): void;
|
|
25
|
+
export declare function cacheMemories(sessionId: string, memories: Memory[]): void;
|
|
26
|
+
export declare function getCachedMemoryById(sessionId: string, memoryId: string): Memory | null;
|
|
27
|
+
export declare function setCachedPreview(sessionId: string, preview: string, msgCount: number): void;
|
|
28
|
+
export declare function getCachedPreview(sessionId: string, currentMsgCount: number): string | null;
|
|
29
|
+
export declare function addInjectionRecord(sessionId: string, record: InjectionRecord): void;
|
|
30
|
+
export declare function commitPendingRecords(sessionId: string): number;
|
|
31
|
+
export declare function hasToolCycleAtPosition(sessionId: string, position: number): boolean;
|
|
32
|
+
export declare function formatAge(updatedAt: string | undefined): string;
|
|
33
|
+
export declare function buildMemoryPreview(memories: Memory[]): string | null;
|
|
34
|
+
export declare function buildExpandedMemory(memory: Memory): string;
|
|
35
|
+
export declare function buildToolDescription(): string;
|
|
36
|
+
export declare function buildDriftRecoveryInjection(pendingCorrection?: string, pendingForcedRecovery?: string): string | null;
|
|
37
|
+
type MessageContent = string | Array<{
|
|
38
|
+
type: string;
|
|
39
|
+
text?: string;
|
|
40
|
+
[key: string]: unknown;
|
|
41
|
+
}>;
|
|
42
|
+
export declare function appendTextToMessage(message: {
|
|
43
|
+
role: string;
|
|
44
|
+
content: MessageContent;
|
|
45
|
+
}, text: string): void;
|
|
46
|
+
export declare function reconstructMessages(messages: Array<{
|
|
47
|
+
role: string;
|
|
48
|
+
content: unknown;
|
|
49
|
+
}>, projectPath: string): {
|
|
50
|
+
messages: Array<{
|
|
51
|
+
role: string;
|
|
52
|
+
content: unknown;
|
|
53
|
+
}>;
|
|
54
|
+
reconstructedCount: number;
|
|
55
|
+
};
|
|
56
|
+
export {};
|