@agentconnect/host 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/host.js +58 -64
- package/dist/providers/claude.d.ts +1 -1
- package/dist/providers/claude.js +13 -5
- package/dist/providers/codex.d.ts +1 -1
- package/dist/providers/codex.js +12 -14
- package/dist/providers/cursor.d.ts +1 -1
- package/dist/providers/cursor.js +5 -4
- package/dist/providers/local.d.ts +1 -1
- package/dist/providers/local.js +8 -2
- package/dist/providers/utils.d.ts +1 -0
- package/dist/providers/utils.js +7 -3
- package/dist/summary.d.ts +0 -6
- package/dist/summary.js +4 -74
- package/dist/types.d.ts +2 -1
- package/package.json +1 -1
package/dist/host.js
CHANGED
|
@@ -5,11 +5,11 @@ import fs from 'fs';
|
|
|
5
5
|
import { promises as fsp } from 'fs';
|
|
6
6
|
import net from 'net';
|
|
7
7
|
import path from 'path';
|
|
8
|
-
import { listModels, listRecentModels, providers, resolveProviderForModel } from './providers/index.js';
|
|
8
|
+
import { listModels, listRecentModels, providers, resolveProviderForModel, } from './providers/index.js';
|
|
9
9
|
import { debugLog, setSpawnLogging } from './providers/utils.js';
|
|
10
10
|
import { createObservedTracker } from './observed.js';
|
|
11
11
|
import { createStorage } from './storage.js';
|
|
12
|
-
import { buildSummaryPrompt, getSummaryModel,
|
|
12
|
+
import { buildSummaryPrompt, getSummaryModel, runSummaryPrompt, } from './summary.js';
|
|
13
13
|
function send(socket, payload) {
|
|
14
14
|
socket.send(JSON.stringify(payload));
|
|
15
15
|
}
|
|
@@ -33,8 +33,7 @@ function buildProviderList(statuses) {
|
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
function resolveLoginExperience(mode) {
|
|
36
|
-
const raw = process.env.AGENTCONNECT_LOGIN_EXPERIENCE ||
|
|
37
|
-
process.env.AGENTCONNECT_CLAUDE_LOGIN_EXPERIENCE;
|
|
36
|
+
const raw = process.env.AGENTCONNECT_LOGIN_EXPERIENCE || process.env.AGENTCONNECT_CLAUDE_LOGIN_EXPERIENCE;
|
|
38
37
|
if (raw) {
|
|
39
38
|
const normalized = raw.trim().toLowerCase();
|
|
40
39
|
if (normalized === 'terminal' || normalized === 'manual')
|
|
@@ -139,6 +138,17 @@ function createHostRuntime(options) {
|
|
|
139
138
|
function recordProviderCapability(providerId) {
|
|
140
139
|
recordCapability(`model.${providerId}`);
|
|
141
140
|
}
|
|
141
|
+
function resolveSystemPrompt(providerId, input) {
|
|
142
|
+
if (typeof input === 'string') {
|
|
143
|
+
const trimmed = input.trim();
|
|
144
|
+
return trimmed ? trimmed : undefined;
|
|
145
|
+
}
|
|
146
|
+
const envKey = `AGENTCONNECT_SYSTEM_PROMPT_${providerId.toUpperCase()}`;
|
|
147
|
+
const envValue = process.env[envKey];
|
|
148
|
+
if (envValue && envValue.trim())
|
|
149
|
+
return envValue.trim();
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
142
152
|
const SUMMARY_REASONING_MAX_LINES = 3;
|
|
143
153
|
const SUMMARY_REASONING_MAX_CHARS = 280;
|
|
144
154
|
function appendSummaryReasoning(session, text) {
|
|
@@ -176,59 +186,45 @@ function createHostRuntime(options) {
|
|
|
176
186
|
}
|
|
177
187
|
async function startPromptSummary(options) {
|
|
178
188
|
const { sessionId, session, message, reasoning, emit } = options;
|
|
179
|
-
if (session.providerId === 'claude')
|
|
180
|
-
return;
|
|
181
189
|
if (session.summaryRequested)
|
|
182
190
|
return;
|
|
183
191
|
session.summaryRequested = true;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
basePath: projectRoot,
|
|
221
|
-
sessionId: providerSessionId,
|
|
222
|
-
});
|
|
223
|
-
if (!summary)
|
|
224
|
-
return;
|
|
225
|
-
persistSummary(emit, sessionId, {
|
|
226
|
-
summary,
|
|
227
|
-
source: 'claude-log',
|
|
228
|
-
provider: 'claude',
|
|
229
|
-
model: session.model ?? null,
|
|
230
|
-
createdAt: new Date().toISOString(),
|
|
231
|
-
}, session);
|
|
192
|
+
try {
|
|
193
|
+
const provider = providers[session.providerId];
|
|
194
|
+
if (!provider)
|
|
195
|
+
return;
|
|
196
|
+
const prompt = buildSummaryPrompt(message, reasoning);
|
|
197
|
+
const summaryModel = getSummaryModel(session.providerId);
|
|
198
|
+
const cwd = session.cwd || basePath;
|
|
199
|
+
const repoRoot = session.repoRoot || basePath;
|
|
200
|
+
const result = await runSummaryPrompt({
|
|
201
|
+
provider,
|
|
202
|
+
prompt,
|
|
203
|
+
model: summaryModel,
|
|
204
|
+
cwd,
|
|
205
|
+
repoRoot,
|
|
206
|
+
});
|
|
207
|
+
if (!result)
|
|
208
|
+
return;
|
|
209
|
+
persistSummary(emit, sessionId, {
|
|
210
|
+
summary: result.summary,
|
|
211
|
+
source: 'prompt',
|
|
212
|
+
provider: session.providerId,
|
|
213
|
+
model: result.model ?? null,
|
|
214
|
+
createdAt: new Date().toISOString(),
|
|
215
|
+
}, session);
|
|
216
|
+
}
|
|
217
|
+
finally {
|
|
218
|
+
session.summaryRequested = false;
|
|
219
|
+
if (session.summarySeed) {
|
|
220
|
+
maybeStartPromptSummary({
|
|
221
|
+
sessionId,
|
|
222
|
+
session,
|
|
223
|
+
emit,
|
|
224
|
+
trigger: 'output',
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
232
228
|
}
|
|
233
229
|
async function getCachedStatus(provider, options = {}) {
|
|
234
230
|
if (options.force) {
|
|
@@ -346,8 +342,6 @@ function createHostRuntime(options) {
|
|
|
346
342
|
}
|
|
347
343
|
function maybeStartPromptSummary(options) {
|
|
348
344
|
const { sessionId, session, emit, trigger } = options;
|
|
349
|
-
if (session.providerId === 'claude')
|
|
350
|
-
return;
|
|
351
345
|
if (session.summaryRequested)
|
|
352
346
|
return;
|
|
353
347
|
if (!session.summarySeed)
|
|
@@ -598,6 +592,7 @@ function createHostRuntime(options) {
|
|
|
598
592
|
model = await pickDefaultModel(rawProvider);
|
|
599
593
|
}
|
|
600
594
|
const reasoningEffort = params.reasoningEffort || null;
|
|
595
|
+
const systemPrompt = resolveSystemPrompt(providerId, params.system);
|
|
601
596
|
const cwd = params.cwd ? resolveAppPathInternal(params.cwd) : undefined;
|
|
602
597
|
const repoRoot = params.repoRoot ? resolveAppPathInternal(params.repoRoot) : undefined;
|
|
603
598
|
const providerDetailLevel = params.providerDetailLevel || undefined;
|
|
@@ -615,6 +610,7 @@ function createHostRuntime(options) {
|
|
|
615
610
|
reasoningEffort,
|
|
616
611
|
cwd,
|
|
617
612
|
repoRoot,
|
|
613
|
+
systemPrompt,
|
|
618
614
|
providerDetailLevel: providerDetailLevel === 'raw' || providerDetailLevel === 'minimal'
|
|
619
615
|
? providerDetailLevel
|
|
620
616
|
: undefined,
|
|
@@ -638,6 +634,9 @@ function createHostRuntime(options) {
|
|
|
638
634
|
if (params.repoRoot) {
|
|
639
635
|
existing.repoRoot = resolveAppPathInternal(params.repoRoot);
|
|
640
636
|
}
|
|
637
|
+
if ('system' in params) {
|
|
638
|
+
existing.systemPrompt = resolveSystemPrompt(existing.providerId, params.system);
|
|
639
|
+
}
|
|
641
640
|
if (params.providerDetailLevel) {
|
|
642
641
|
const level = String(params.providerDetailLevel);
|
|
643
642
|
if (level === 'raw' || level === 'minimal') {
|
|
@@ -699,10 +698,7 @@ function createHostRuntime(options) {
|
|
|
699
698
|
return;
|
|
700
699
|
}
|
|
701
700
|
}
|
|
702
|
-
if (message.trim()
|
|
703
|
-
session.providerId !== 'claude' &&
|
|
704
|
-
!session.summaryRequested &&
|
|
705
|
-
!session.summarySeed) {
|
|
701
|
+
if (message.trim()) {
|
|
706
702
|
session.summarySeed = message;
|
|
707
703
|
session.summaryReasoning = '';
|
|
708
704
|
}
|
|
@@ -726,6 +722,7 @@ function createHostRuntime(options) {
|
|
|
726
722
|
repoRoot,
|
|
727
723
|
cwd,
|
|
728
724
|
providerDetailLevel,
|
|
725
|
+
system: session.systemPrompt,
|
|
729
726
|
signal: controller.signal,
|
|
730
727
|
onEvent: (event) => {
|
|
731
728
|
const current = activeRuns.get(sessionId);
|
|
@@ -746,9 +743,7 @@ function createHostRuntime(options) {
|
|
|
746
743
|
trigger: 'reasoning',
|
|
747
744
|
});
|
|
748
745
|
}
|
|
749
|
-
if (event.type === 'delta' ||
|
|
750
|
-
event.type === 'message' ||
|
|
751
|
-
event.type === 'final') {
|
|
746
|
+
if (event.type === 'delta' || event.type === 'message' || event.type === 'final') {
|
|
752
747
|
maybeStartPromptSummary({
|
|
753
748
|
sessionId,
|
|
754
749
|
session,
|
|
@@ -765,7 +760,6 @@ function createHostRuntime(options) {
|
|
|
765
760
|
return;
|
|
766
761
|
if (result?.sessionId) {
|
|
767
762
|
session.providerSessionId = result.sessionId;
|
|
768
|
-
void startClaudeLogSummary({ sessionId, session, emit: responder.emit });
|
|
769
763
|
}
|
|
770
764
|
})
|
|
771
765
|
.catch((err) => {
|
|
@@ -9,4 +9,4 @@ export declare function updateClaude(): Promise<ProviderStatus>;
|
|
|
9
9
|
export declare function loginClaude(options?: ProviderLoginOptions): Promise<{
|
|
10
10
|
loggedIn: boolean;
|
|
11
11
|
}>;
|
|
12
|
-
export declare function runClaudePrompt({ prompt, resumeSessionId, model, cwd, providerDetailLevel, onEvent, signal, }: RunPromptOptions): Promise<RunPromptResult>;
|
|
12
|
+
export declare function runClaudePrompt({ prompt, system, resumeSessionId, model, cwd, providerDetailLevel, onEvent, signal, }: RunPromptOptions): Promise<RunPromptResult>;
|
package/dist/providers/claude.js
CHANGED
|
@@ -184,7 +184,10 @@ function formatClaudeDisplayName(modelId) {
|
|
|
184
184
|
const value = modelId.trim();
|
|
185
185
|
if (!value.startsWith('claude-'))
|
|
186
186
|
return value;
|
|
187
|
-
const parts = value
|
|
187
|
+
const parts = value
|
|
188
|
+
.replace(/^claude-/, '')
|
|
189
|
+
.split('-')
|
|
190
|
+
.filter(Boolean);
|
|
188
191
|
if (!parts.length)
|
|
189
192
|
return value;
|
|
190
193
|
const family = parts[0];
|
|
@@ -560,8 +563,7 @@ async function checkClaudeCliStatus() {
|
|
|
560
563
|
: typeof message?.error === 'string'
|
|
561
564
|
? message.error
|
|
562
565
|
: '';
|
|
563
|
-
if (isClaudeAuthErrorText(text) ||
|
|
564
|
-
(errorText && isClaudeAuthErrorText(errorText))) {
|
|
566
|
+
if (isClaudeAuthErrorText(text) || (errorText && isClaudeAuthErrorText(errorText))) {
|
|
565
567
|
authError = authError ?? (text || errorText);
|
|
566
568
|
}
|
|
567
569
|
else if (text.trim()) {
|
|
@@ -960,7 +962,7 @@ function extractResultText(msg) {
|
|
|
960
962
|
const text = msg.result;
|
|
961
963
|
return typeof text === 'string' && text ? text : null;
|
|
962
964
|
}
|
|
963
|
-
export function runClaudePrompt({ prompt, resumeSessionId, model, cwd, providerDetailLevel, onEvent, signal, }) {
|
|
965
|
+
export function runClaudePrompt({ prompt, system, resumeSessionId, model, cwd, providerDetailLevel, onEvent, signal, }) {
|
|
964
966
|
return new Promise((resolve) => {
|
|
965
967
|
const command = getClaudeCommand();
|
|
966
968
|
const args = [
|
|
@@ -970,6 +972,10 @@ export function runClaudePrompt({ prompt, resumeSessionId, model, cwd, providerD
|
|
|
970
972
|
'--permission-mode',
|
|
971
973
|
'bypassPermissions',
|
|
972
974
|
];
|
|
975
|
+
const systemPrompt = typeof system === 'string' ? system.trim() : '';
|
|
976
|
+
if (systemPrompt) {
|
|
977
|
+
args.push('--append-system-prompt', systemPrompt);
|
|
978
|
+
}
|
|
973
979
|
const modelValue = mapClaudeModel(model);
|
|
974
980
|
if (modelValue) {
|
|
975
981
|
args.push('--model', modelValue);
|
|
@@ -1063,7 +1069,9 @@ export function runClaudePrompt({ prompt, resumeSessionId, model, cwd, providerD
|
|
|
1063
1069
|
const index = typeof msg.event.index === 'number' ? msg.event.index : undefined;
|
|
1064
1070
|
const block = msg.event.content_block;
|
|
1065
1071
|
if (evType === 'content_block_start' && block && typeof index === 'number') {
|
|
1066
|
-
if (block.type === 'tool_use' ||
|
|
1072
|
+
if (block.type === 'tool_use' ||
|
|
1073
|
+
block.type === 'server_tool_use' ||
|
|
1074
|
+
block.type === 'mcp_tool_use') {
|
|
1067
1075
|
toolBlocks.set(index, { id: block.id, name: block.name });
|
|
1068
1076
|
emit({
|
|
1069
1077
|
type: 'tool_call',
|
|
@@ -8,4 +8,4 @@ export declare function loginCodex(): Promise<{
|
|
|
8
8
|
loggedIn: boolean;
|
|
9
9
|
}>;
|
|
10
10
|
export declare function listCodexModels(): Promise<ModelInfo[]>;
|
|
11
|
-
export declare function runCodexPrompt({ prompt, resumeSessionId, model, reasoningEffort, repoRoot, cwd, providerDetailLevel, onEvent, signal, }: RunPromptOptions): Promise<RunPromptResult>;
|
|
11
|
+
export declare function runCodexPrompt({ prompt, system, resumeSessionId, model, reasoningEffort, repoRoot, cwd, providerDetailLevel, onEvent, signal, }: RunPromptOptions): Promise<RunPromptResult>;
|
package/dist/providers/codex.js
CHANGED
|
@@ -3,7 +3,7 @@ import { readFile } from 'fs/promises';
|
|
|
3
3
|
import https from 'https';
|
|
4
4
|
import os from 'os';
|
|
5
5
|
import path from 'path';
|
|
6
|
-
import { buildInstallCommandAuto, buildLoginCommand, buildStatusCommand, checkCommandVersion, commandExists, createLineParser, debugLog, logProviderSpawn, resolveWindowsCommand, resolveCommandPath, resolveCommandRealPath, runCommand, } from './utils.js';
|
|
6
|
+
import { buildInstallCommandAuto, buildLoginCommand, buildStatusCommand, checkCommandVersion, commandExists, createLineParser, applySystemPrompt, debugLog, logProviderSpawn, resolveWindowsCommand, resolveCommandPath, resolveCommandRealPath, runCommand, } from './utils.js';
|
|
7
7
|
const CODEX_PACKAGE = '@openai/codex';
|
|
8
8
|
const DEFAULT_LOGIN = 'codex login';
|
|
9
9
|
const DEFAULT_STATUS = 'codex login status';
|
|
@@ -237,9 +237,7 @@ function buildCodexExecArgs(options) {
|
|
|
237
237
|
}
|
|
238
238
|
args.push('--yolo');
|
|
239
239
|
const summarySetting = process.env.AGENTCONNECT_CODEX_REASONING_SUMMARY;
|
|
240
|
-
const summary = summarySetting && summarySetting.trim()
|
|
241
|
-
? summarySetting.trim()
|
|
242
|
-
: 'detailed';
|
|
240
|
+
const summary = summarySetting && summarySetting.trim() ? summarySetting.trim() : 'detailed';
|
|
243
241
|
const summaryDisabled = ['0', 'false', 'off', 'none'].includes(summary.toLowerCase());
|
|
244
242
|
if (!summaryDisabled) {
|
|
245
243
|
args.push('--config', `model_reasoning_summary=${summary}`);
|
|
@@ -329,7 +327,9 @@ export async function getCodexStatus() {
|
|
|
329
327
|
const status = buildStatusCommand('AGENTCONNECT_CODEX_STATUS', DEFAULT_STATUS);
|
|
330
328
|
if (status.command) {
|
|
331
329
|
const statusCommand = resolveWindowsCommand(status.command);
|
|
332
|
-
const result = await runCommand(statusCommand, status.args, {
|
|
330
|
+
const result = await runCommand(statusCommand, status.args, {
|
|
331
|
+
env: { ...process.env, CI: '1' },
|
|
332
|
+
});
|
|
333
333
|
const output = `${result.stdout}\n${result.stderr}`.toLowerCase();
|
|
334
334
|
if (output.includes('not logged in') ||
|
|
335
335
|
output.includes('not logged') ||
|
|
@@ -644,16 +644,17 @@ export async function listCodexModels() {
|
|
|
644
644
|
// Fetch failed - return empty, don't cache so it retries next time
|
|
645
645
|
return [];
|
|
646
646
|
}
|
|
647
|
-
export function runCodexPrompt({ prompt, resumeSessionId, model, reasoningEffort, repoRoot, cwd, providerDetailLevel, onEvent, signal, }) {
|
|
647
|
+
export function runCodexPrompt({ prompt, system, resumeSessionId, model, reasoningEffort, repoRoot, cwd, providerDetailLevel, onEvent, signal, }) {
|
|
648
648
|
return new Promise((resolve) => {
|
|
649
649
|
const command = getCodexCommand();
|
|
650
650
|
const resolvedRepoRoot = repoRoot ? path.resolve(repoRoot) : null;
|
|
651
651
|
const resolvedCwd = cwd ? path.resolve(cwd) : null;
|
|
652
652
|
const runDir = resolvedCwd || resolvedRepoRoot || process.cwd();
|
|
653
653
|
const cdTarget = resolvedRepoRoot || resolvedCwd || '.';
|
|
654
|
+
const composedPrompt = applySystemPrompt(system, prompt);
|
|
654
655
|
const runAttempt = (mode) => new Promise((attemptResolve) => {
|
|
655
656
|
const args = buildCodexExecArgs({
|
|
656
|
-
prompt,
|
|
657
|
+
prompt: composedPrompt,
|
|
657
658
|
cdTarget,
|
|
658
659
|
resumeSessionId,
|
|
659
660
|
model,
|
|
@@ -893,9 +894,7 @@ export function runCodexPrompt({ prompt, resumeSessionId, model, reasoningEffort
|
|
|
893
894
|
}
|
|
894
895
|
if (isTerminalEvent(ev) && !didFinalize) {
|
|
895
896
|
if (ev.type === 'turn.failed') {
|
|
896
|
-
const message = typeof ev.error?.message === 'string'
|
|
897
|
-
? ev.error.message
|
|
898
|
-
: pendingError?.message;
|
|
897
|
+
const message = typeof ev.error?.message === 'string' ? ev.error.message : pendingError?.message;
|
|
899
898
|
emitError(message ?? 'Codex run failed', providerDetail);
|
|
900
899
|
didFinalize = true;
|
|
901
900
|
handled = true;
|
|
@@ -921,10 +920,9 @@ export function runCodexPrompt({ prompt, resumeSessionId, model, reasoningEffort
|
|
|
921
920
|
const hint = stderrLines.at(-1) || stdoutLines.at(-1) || '';
|
|
922
921
|
const context = pendingError?.message || hint;
|
|
923
922
|
const suffix = context ? `: ${context}` : '';
|
|
924
|
-
const fallback = mode === 'modern' &&
|
|
925
|
-
|
|
926
|
-
...stdoutLines
|
|
927
|
-
]);
|
|
923
|
+
const fallback = mode === 'modern' &&
|
|
924
|
+
!sawJson &&
|
|
925
|
+
shouldFallbackToLegacy([...stderrLines, ...stdoutLines]);
|
|
928
926
|
debugLog('Codex', 'exit', {
|
|
929
927
|
code,
|
|
930
928
|
stderr: stderrLines,
|
|
@@ -8,4 +8,4 @@ export declare function updateCursor(): Promise<ProviderStatus>;
|
|
|
8
8
|
export declare function loginCursor(options?: ProviderLoginOptions): Promise<{
|
|
9
9
|
loggedIn: boolean;
|
|
10
10
|
}>;
|
|
11
|
-
export declare function runCursorPrompt({ prompt, resumeSessionId, model, repoRoot, cwd, providerDetailLevel, onEvent, signal, }: RunPromptOptions): Promise<RunPromptResult>;
|
|
11
|
+
export declare function runCursorPrompt({ prompt, system, resumeSessionId, model, repoRoot, cwd, providerDetailLevel, onEvent, signal, }: RunPromptOptions): Promise<RunPromptResult>;
|
package/dist/providers/cursor.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { buildInstallCommand, buildLoginCommand, buildStatusCommand, checkCommandVersion, commandExists, createLineParser, debugLog, logProviderSpawn, resolveWindowsCommand, resolveCommandPath, resolveCommandRealPath, runCommand, } from './utils.js';
|
|
3
|
+
import { buildInstallCommand, buildLoginCommand, buildStatusCommand, checkCommandVersion, commandExists, createLineParser, applySystemPrompt, debugLog, logProviderSpawn, resolveWindowsCommand, resolveCommandPath, resolveCommandRealPath, runCommand, } from './utils.js';
|
|
4
4
|
const INSTALL_UNIX = 'curl https://cursor.com/install -fsS | bash';
|
|
5
5
|
const DEFAULT_LOGIN = 'cursor-agent login';
|
|
6
6
|
const DEFAULT_STATUS = 'cursor-agent status';
|
|
@@ -611,7 +611,7 @@ function extractErrorMessage(ev) {
|
|
|
611
611
|
return ev.result;
|
|
612
612
|
return null;
|
|
613
613
|
}
|
|
614
|
-
export function runCursorPrompt({ prompt, resumeSessionId, model, repoRoot, cwd, providerDetailLevel, onEvent, signal, }) {
|
|
614
|
+
export function runCursorPrompt({ prompt, system, resumeSessionId, model, repoRoot, cwd, providerDetailLevel, onEvent, signal, }) {
|
|
615
615
|
return new Promise((resolve) => {
|
|
616
616
|
const command = getCursorCommand();
|
|
617
617
|
const resolvedRepoRoot = repoRoot ? path.resolve(repoRoot) : null;
|
|
@@ -630,7 +630,8 @@ export function runCursorPrompt({ prompt, resumeSessionId, model, repoRoot, cwd,
|
|
|
630
630
|
if (endpoint) {
|
|
631
631
|
args.push('--endpoint', endpoint);
|
|
632
632
|
}
|
|
633
|
-
|
|
633
|
+
const composedPrompt = applySystemPrompt(system, prompt);
|
|
634
|
+
args.push(composedPrompt);
|
|
634
635
|
logProviderSpawn({
|
|
635
636
|
provider: 'cursor',
|
|
636
637
|
command,
|
|
@@ -650,7 +651,7 @@ export function runCursorPrompt({ prompt, resumeSessionId, model, repoRoot, cwd,
|
|
|
650
651
|
endpoint: endpoint || null,
|
|
651
652
|
resume: resumeSessionId || null,
|
|
652
653
|
apiKeyConfigured: Boolean(getCursorApiKey().trim()),
|
|
653
|
-
promptChars:
|
|
654
|
+
promptChars: composedPrompt.length,
|
|
654
655
|
});
|
|
655
656
|
const child = spawn(command, args, {
|
|
656
657
|
cwd: runDir,
|
|
@@ -6,4 +6,4 @@ export declare function loginLocal(options?: ProviderLoginOptions): Promise<{
|
|
|
6
6
|
loggedIn: boolean;
|
|
7
7
|
}>;
|
|
8
8
|
export declare function listLocalModels(): Promise<ModelInfo[]>;
|
|
9
|
-
export declare function runLocalPrompt({ prompt, model, onEvent, }: RunPromptOptions): Promise<RunPromptResult>;
|
|
9
|
+
export declare function runLocalPrompt({ prompt, system, model, onEvent, }: RunPromptOptions): Promise<RunPromptResult>;
|
package/dist/providers/local.js
CHANGED
|
@@ -76,7 +76,7 @@ export async function listLocalModels() {
|
|
|
76
76
|
.map((entry) => ({ id: entry.id, provider: 'local', displayName: entry.id }))
|
|
77
77
|
.filter((entry) => entry.id);
|
|
78
78
|
}
|
|
79
|
-
export async function runLocalPrompt({ prompt, model, onEvent, }) {
|
|
79
|
+
export async function runLocalPrompt({ prompt, system, model, onEvent, }) {
|
|
80
80
|
const base = getLocalBaseUrl();
|
|
81
81
|
const fallback = process.env.AGENTCONNECT_LOCAL_MODEL || '';
|
|
82
82
|
const resolvedModel = resolveLocalModel(model, fallback);
|
|
@@ -90,9 +90,15 @@ export async function runLocalPrompt({ prompt, model, onEvent, }) {
|
|
|
90
90
|
args: ['--base-url', base, '--model', resolvedModel, prompt],
|
|
91
91
|
cwd: process.cwd(),
|
|
92
92
|
});
|
|
93
|
+
const messages = [];
|
|
94
|
+
const systemPrompt = typeof system === 'string' ? system.trim() : '';
|
|
95
|
+
if (systemPrompt) {
|
|
96
|
+
messages.push({ role: 'system', content: systemPrompt });
|
|
97
|
+
}
|
|
98
|
+
messages.push({ role: 'user', content: prompt });
|
|
93
99
|
const payload = {
|
|
94
100
|
model: resolvedModel,
|
|
95
|
-
messages
|
|
101
|
+
messages,
|
|
96
102
|
stream: false,
|
|
97
103
|
};
|
|
98
104
|
const headers = { 'Content-Type': 'application/json' };
|
|
@@ -10,6 +10,7 @@ export declare function logProviderSpawn(options: {
|
|
|
10
10
|
redactIndex?: number;
|
|
11
11
|
}): void;
|
|
12
12
|
export declare function debugLog(scope: string, message: string, details?: Record<string, unknown>): void;
|
|
13
|
+
export declare function applySystemPrompt(system: string | undefined, prompt: string): string;
|
|
13
14
|
export interface SplitCommandResult {
|
|
14
15
|
command: string;
|
|
15
16
|
args: string[];
|
package/dist/providers/utils.js
CHANGED
|
@@ -17,9 +17,7 @@ export function logProviderSpawn(options) {
|
|
|
17
17
|
}
|
|
18
18
|
const cwd = options.cwd || process.cwd();
|
|
19
19
|
const formatted = formatShellCommand(options.command, redacted);
|
|
20
|
-
const fullCommand = cwd
|
|
21
|
-
? `${formatShellCommand('cd', [cwd])} && ${formatted}`
|
|
22
|
-
: formatted;
|
|
20
|
+
const fullCommand = cwd ? `${formatShellCommand('cd', [cwd])} && ${formatted}` : formatted;
|
|
23
21
|
console.log(`AgentConnect: ${fullCommand}`);
|
|
24
22
|
}
|
|
25
23
|
function formatShellCommand(command, args) {
|
|
@@ -46,6 +44,12 @@ export function debugLog(scope, message, details) {
|
|
|
46
44
|
}
|
|
47
45
|
console.log(`[AgentConnect][${scope}] ${message}${suffix}`);
|
|
48
46
|
}
|
|
47
|
+
export function applySystemPrompt(system, prompt) {
|
|
48
|
+
const trimmed = typeof system === 'string' ? system.trim() : '';
|
|
49
|
+
if (!trimmed)
|
|
50
|
+
return prompt;
|
|
51
|
+
return `<<SYSTEM>>\n${trimmed}\n<</SYSTEM>>\n\n<<USER>>\n${prompt}`;
|
|
52
|
+
}
|
|
49
53
|
export function splitCommand(value) {
|
|
50
54
|
if (!value)
|
|
51
55
|
return { command: '', args: [] };
|
package/dist/summary.d.ts
CHANGED
|
@@ -21,9 +21,3 @@ export declare function runSummaryPrompt(options: {
|
|
|
21
21
|
summary: string;
|
|
22
22
|
model?: string | null;
|
|
23
23
|
} | null>;
|
|
24
|
-
export declare function pollClaudeSummary(options: {
|
|
25
|
-
basePath: string;
|
|
26
|
-
sessionId: string;
|
|
27
|
-
timeoutMs?: number;
|
|
28
|
-
intervalMs?: number;
|
|
29
|
-
}): Promise<string | null>;
|
package/dist/summary.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import { promises as fsp } from 'fs';
|
|
3
|
-
import os from 'os';
|
|
4
|
-
import path from 'path';
|
|
5
1
|
const SUMMARY_MODEL_OVERRIDES = {
|
|
6
2
|
claude: 'haiku',
|
|
7
3
|
codex: 'gpt-5.1-codex-mini',
|
|
@@ -47,7 +43,10 @@ export function buildSummaryPrompt(userPrompt, reasoning) {
|
|
|
47
43
|
return lines.join('\n');
|
|
48
44
|
}
|
|
49
45
|
export function sanitizeSummary(raw) {
|
|
50
|
-
const normalized = raw
|
|
46
|
+
const normalized = raw
|
|
47
|
+
.replace(/[\r\n]+/g, ' ')
|
|
48
|
+
.replace(/\s+/g, ' ')
|
|
49
|
+
.trim();
|
|
51
50
|
const stripped = normalized.replace(/^["']+|["']+$/g, '').trim();
|
|
52
51
|
const cleaned = stripped.replace(/[.!?]+$/g, '').trim();
|
|
53
52
|
if (!cleaned)
|
|
@@ -107,72 +106,3 @@ export async function runSummaryPrompt(options) {
|
|
|
107
106
|
}
|
|
108
107
|
return attempt(null);
|
|
109
108
|
}
|
|
110
|
-
function buildClaudeProjectKey(basePath) {
|
|
111
|
-
const resolved = path.resolve(basePath);
|
|
112
|
-
const normalized = resolved.split(path.sep).filter(Boolean).join('-');
|
|
113
|
-
return `-${normalized}`;
|
|
114
|
-
}
|
|
115
|
-
function resolveClaudeSummaryPath(basePath, sessionId) {
|
|
116
|
-
if (!sessionId)
|
|
117
|
-
return null;
|
|
118
|
-
const root = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude');
|
|
119
|
-
const projectKey = buildClaudeProjectKey(basePath);
|
|
120
|
-
return path.join(root, 'projects', projectKey, `${sessionId}.jsonl`);
|
|
121
|
-
}
|
|
122
|
-
async function readClaudeSummaryFile(filePath) {
|
|
123
|
-
if (!fs.existsSync(filePath))
|
|
124
|
-
return null;
|
|
125
|
-
try {
|
|
126
|
-
const raw = await fsp.readFile(filePath, 'utf8');
|
|
127
|
-
let latest = null;
|
|
128
|
-
for (const line of raw.split(/\r?\n/)) {
|
|
129
|
-
if (!line.trim())
|
|
130
|
-
continue;
|
|
131
|
-
let parsed;
|
|
132
|
-
try {
|
|
133
|
-
parsed = JSON.parse(line);
|
|
134
|
-
}
|
|
135
|
-
catch {
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
138
|
-
if (!parsed || typeof parsed !== 'object')
|
|
139
|
-
continue;
|
|
140
|
-
const record = parsed;
|
|
141
|
-
if (record.type !== 'summary')
|
|
142
|
-
continue;
|
|
143
|
-
const summary = record.summary;
|
|
144
|
-
if (typeof summary === 'string' && summary.trim()) {
|
|
145
|
-
latest = summary.trim();
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return latest ? sanitizeSummary(latest) : null;
|
|
149
|
-
}
|
|
150
|
-
catch {
|
|
151
|
-
return null;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
export async function pollClaudeSummary(options) {
|
|
155
|
-
const { basePath, sessionId, timeoutMs = 30000, intervalMs = 1500 } = options;
|
|
156
|
-
const filePath = resolveClaudeSummaryPath(basePath, sessionId);
|
|
157
|
-
if (!filePath)
|
|
158
|
-
return null;
|
|
159
|
-
const start = Date.now();
|
|
160
|
-
let lastMtime = 0;
|
|
161
|
-
while (Date.now() - start < timeoutMs) {
|
|
162
|
-
try {
|
|
163
|
-
const stat = await fsp.stat(filePath);
|
|
164
|
-
const mtime = stat.mtimeMs;
|
|
165
|
-
if (mtime !== lastMtime) {
|
|
166
|
-
lastMtime = mtime;
|
|
167
|
-
const summary = await readClaudeSummaryFile(filePath);
|
|
168
|
-
if (summary)
|
|
169
|
-
return summary;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
catch {
|
|
173
|
-
// ignore
|
|
174
|
-
}
|
|
175
|
-
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
176
|
-
}
|
|
177
|
-
return null;
|
|
178
|
-
}
|
package/dist/types.d.ts
CHANGED
|
@@ -152,6 +152,7 @@ export interface SessionEvent {
|
|
|
152
152
|
}
|
|
153
153
|
export interface RunPromptOptions {
|
|
154
154
|
prompt: string;
|
|
155
|
+
system?: string;
|
|
155
156
|
resumeSessionId?: string | null;
|
|
156
157
|
model?: string;
|
|
157
158
|
reasoningEffort?: string | null;
|
|
@@ -193,8 +194,8 @@ export interface SessionState {
|
|
|
193
194
|
cwd?: string;
|
|
194
195
|
repoRoot?: string;
|
|
195
196
|
providerDetailLevel?: ProviderDetailLevel;
|
|
197
|
+
systemPrompt?: string;
|
|
196
198
|
summaryRequested?: boolean;
|
|
197
|
-
claudeSummaryWatch?: boolean;
|
|
198
199
|
summarySeed?: string;
|
|
199
200
|
summaryReasoning?: string;
|
|
200
201
|
summary?: string | null;
|