init claude-code
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* Shared helpers for building the API cache-key prefix (systemPrompt,
|
||||
* userContext, systemContext) for query() calls.
|
||||
*
|
||||
* Lives in its own file because it imports from context.ts and
|
||||
* constants/prompts.ts, which are high in the dependency graph. Putting
|
||||
* these imports in systemPrompt.ts or sideQuestion.ts (both reachable
|
||||
* from commands.ts) would create cycles. Only entrypoint-layer files
|
||||
* import from here (QueryEngine.ts, cli/print.ts).
|
||||
*/
|
||||
|
||||
import type { Command } from '../commands.js'
|
||||
import { getSystemPrompt } from '../constants/prompts.js'
|
||||
import { getSystemContext, getUserContext } from '../context.js'
|
||||
import type { MCPServerConnection } from '../services/mcp/types.js'
|
||||
import type { AppState } from '../state/AppStateStore.js'
|
||||
import type { Tools, ToolUseContext } from '../Tool.js'
|
||||
import type { AgentDefinition } from '../tools/AgentTool/loadAgentsDir.js'
|
||||
import type { Message } from '../types/message.js'
|
||||
import { createAbortController } from './abortController.js'
|
||||
import type { FileStateCache } from './fileStateCache.js'
|
||||
import type { CacheSafeParams } from './forkedAgent.js'
|
||||
import { getMainLoopModel } from './model/model.js'
|
||||
import { asSystemPrompt } from './systemPromptType.js'
|
||||
import {
|
||||
shouldEnableThinkingByDefault,
|
||||
type ThinkingConfig,
|
||||
} from './thinking.js'
|
||||
|
||||
/**
|
||||
* Fetch the three context pieces that form the API cache-key prefix:
|
||||
* systemPrompt parts, userContext, systemContext.
|
||||
*
|
||||
* When customSystemPrompt is set, the default getSystemPrompt build and
|
||||
* getSystemContext are skipped — the custom prompt replaces the default
|
||||
* entirely, and systemContext would be appended to a default that isn't
|
||||
* being used.
|
||||
*
|
||||
* Callers assemble the final systemPrompt from defaultSystemPrompt (or
|
||||
* customSystemPrompt) + optional extras + appendSystemPrompt. QueryEngine
|
||||
* injects coordinator userContext and memory-mechanics prompt on top;
|
||||
* sideQuestion's fallback uses the base result directly.
|
||||
*/
|
||||
export async function fetchSystemPromptParts({
|
||||
tools,
|
||||
mainLoopModel,
|
||||
additionalWorkingDirectories,
|
||||
mcpClients,
|
||||
customSystemPrompt,
|
||||
}: {
|
||||
tools: Tools
|
||||
mainLoopModel: string
|
||||
additionalWorkingDirectories: string[]
|
||||
mcpClients: MCPServerConnection[]
|
||||
customSystemPrompt: string | undefined
|
||||
}): Promise<{
|
||||
defaultSystemPrompt: string[]
|
||||
userContext: { [k: string]: string }
|
||||
systemContext: { [k: string]: string }
|
||||
}> {
|
||||
const [defaultSystemPrompt, userContext, systemContext] = await Promise.all([
|
||||
customSystemPrompt !== undefined
|
||||
? Promise.resolve([])
|
||||
: getSystemPrompt(
|
||||
tools,
|
||||
mainLoopModel,
|
||||
additionalWorkingDirectories,
|
||||
mcpClients,
|
||||
),
|
||||
getUserContext(),
|
||||
customSystemPrompt !== undefined ? Promise.resolve({}) : getSystemContext(),
|
||||
])
|
||||
return { defaultSystemPrompt, userContext, systemContext }
|
||||
}
|
||||
|
||||
/**
|
||||
* Build CacheSafeParams from raw inputs when getLastCacheSafeParams() is null.
|
||||
*
|
||||
* Used by the SDK side_question handler (print.ts) on resume before a turn
|
||||
* completes — there's no stopHooks snapshot yet. Mirrors the system prompt
|
||||
* assembly in QueryEngine.ts:ask() so the rebuilt prefix matches what the
|
||||
* main loop will send, preserving the cache hit in the common case.
|
||||
*
|
||||
* May still miss the cache if the main loop applies extras this path doesn't
|
||||
* know about (coordinator mode, memory-mechanics prompt). That's acceptable —
|
||||
* the alternative is returning null and failing the side question entirely.
|
||||
*/
|
||||
export async function buildSideQuestionFallbackParams({
|
||||
tools,
|
||||
commands,
|
||||
mcpClients,
|
||||
messages,
|
||||
readFileState,
|
||||
getAppState,
|
||||
setAppState,
|
||||
customSystemPrompt,
|
||||
appendSystemPrompt,
|
||||
thinkingConfig,
|
||||
agents,
|
||||
}: {
|
||||
tools: Tools
|
||||
commands: Command[]
|
||||
mcpClients: MCPServerConnection[]
|
||||
messages: Message[]
|
||||
readFileState: FileStateCache
|
||||
getAppState: () => AppState
|
||||
setAppState: (f: (prev: AppState) => AppState) => void
|
||||
customSystemPrompt: string | undefined
|
||||
appendSystemPrompt: string | undefined
|
||||
thinkingConfig: ThinkingConfig | undefined
|
||||
agents: AgentDefinition[]
|
||||
}): Promise<CacheSafeParams> {
|
||||
const mainLoopModel = getMainLoopModel()
|
||||
const appState = getAppState()
|
||||
|
||||
const { defaultSystemPrompt, userContext, systemContext } =
|
||||
await fetchSystemPromptParts({
|
||||
tools,
|
||||
mainLoopModel,
|
||||
additionalWorkingDirectories: Array.from(
|
||||
appState.toolPermissionContext.additionalWorkingDirectories.keys(),
|
||||
),
|
||||
mcpClients,
|
||||
customSystemPrompt,
|
||||
})
|
||||
|
||||
const systemPrompt = asSystemPrompt([
|
||||
...(customSystemPrompt !== undefined
|
||||
? [customSystemPrompt]
|
||||
: defaultSystemPrompt),
|
||||
...(appendSystemPrompt ? [appendSystemPrompt] : []),
|
||||
])
|
||||
|
||||
// Strip in-progress assistant message (stop_reason === null) — same guard
|
||||
// as btw.tsx. The SDK can fire side_question mid-turn.
|
||||
const last = messages.at(-1)
|
||||
const forkContextMessages =
|
||||
last?.type === 'assistant' && last.message.stop_reason === null
|
||||
? messages.slice(0, -1)
|
||||
: messages
|
||||
|
||||
const toolUseContext: ToolUseContext = {
|
||||
options: {
|
||||
commands,
|
||||
debug: false,
|
||||
mainLoopModel,
|
||||
tools,
|
||||
verbose: false,
|
||||
thinkingConfig:
|
||||
thinkingConfig ??
|
||||
(shouldEnableThinkingByDefault() !== false
|
||||
? { type: 'adaptive' }
|
||||
: { type: 'disabled' }),
|
||||
mcpClients,
|
||||
mcpResources: {},
|
||||
isNonInteractiveSession: true,
|
||||
agentDefinitions: { activeAgents: agents, allAgents: [] },
|
||||
customSystemPrompt,
|
||||
appendSystemPrompt,
|
||||
},
|
||||
abortController: createAbortController(),
|
||||
readFileState,
|
||||
getAppState,
|
||||
setAppState,
|
||||
messages: forkContextMessages,
|
||||
setInProgressToolUseIDs: () => {},
|
||||
setResponseLength: () => {},
|
||||
updateFileHistoryState: () => {},
|
||||
updateAttributionState: () => {},
|
||||
}
|
||||
|
||||
return {
|
||||
systemPrompt,
|
||||
userContext,
|
||||
systemContext,
|
||||
toolUseContext,
|
||||
forkContextMessages,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user