chore: initialize recovered claude workspace
This commit is contained in:
123
src/utils/systemPrompt.ts
Normal file
123
src/utils/systemPrompt.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import { feature } from 'bun:bundle'
|
||||
import {
|
||||
type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
logEvent,
|
||||
} from '../services/analytics/index.js'
|
||||
import type { ToolUseContext } from '../Tool.js'
|
||||
import type { AgentDefinition } from '../tools/AgentTool/loadAgentsDir.js'
|
||||
import { isBuiltInAgent } from '../tools/AgentTool/loadAgentsDir.js'
|
||||
import { isEnvTruthy } from './envUtils.js'
|
||||
import { asSystemPrompt, type SystemPrompt } from './systemPromptType.js'
|
||||
|
||||
export { asSystemPrompt, type SystemPrompt } from './systemPromptType.js'
|
||||
|
||||
// Dead code elimination: conditional import for proactive mode.
|
||||
// Same pattern as prompts.ts — lazy require to avoid pulling the module
|
||||
// into non-proactive builds.
|
||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||
const proactiveModule =
|
||||
feature('PROACTIVE') || feature('KAIROS')
|
||||
? (require('../proactive/index.js') as typeof import('../proactive/index.js'))
|
||||
: null
|
||||
/* eslint-enable @typescript-eslint/no-require-imports */
|
||||
|
||||
function isProactiveActive_SAFE_TO_CALL_ANYWHERE(): boolean {
|
||||
return proactiveModule?.isProactiveActive() ?? false
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the effective system prompt array based on priority:
|
||||
* 0. Override system prompt (if set, e.g., via loop mode - REPLACES all other prompts)
|
||||
* 1. Coordinator system prompt (if coordinator mode is active)
|
||||
* 2. Agent system prompt (if mainThreadAgentDefinition is set)
|
||||
* - In proactive mode: agent prompt is APPENDED to default (agent adds domain
|
||||
* instructions on top of the autonomous agent prompt, like teammates do)
|
||||
* - Otherwise: agent prompt REPLACES default
|
||||
* 3. Custom system prompt (if specified via --system-prompt)
|
||||
* 4. Default system prompt (the standard Claude Code prompt)
|
||||
*
|
||||
* Plus appendSystemPrompt is always added at the end if specified (except when override is set).
|
||||
*/
|
||||
export function buildEffectiveSystemPrompt({
|
||||
mainThreadAgentDefinition,
|
||||
toolUseContext,
|
||||
customSystemPrompt,
|
||||
defaultSystemPrompt,
|
||||
appendSystemPrompt,
|
||||
overrideSystemPrompt,
|
||||
}: {
|
||||
mainThreadAgentDefinition: AgentDefinition | undefined
|
||||
toolUseContext: Pick<ToolUseContext, 'options'>
|
||||
customSystemPrompt: string | undefined
|
||||
defaultSystemPrompt: string[]
|
||||
appendSystemPrompt: string | undefined
|
||||
overrideSystemPrompt?: string | null
|
||||
}): SystemPrompt {
|
||||
if (overrideSystemPrompt) {
|
||||
return asSystemPrompt([overrideSystemPrompt])
|
||||
}
|
||||
// Coordinator mode: use coordinator prompt instead of default
|
||||
// Use inline env check instead of coordinatorModule to avoid circular
|
||||
// dependency issues during test module loading.
|
||||
if (
|
||||
feature('COORDINATOR_MODE') &&
|
||||
isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE) &&
|
||||
!mainThreadAgentDefinition
|
||||
) {
|
||||
// Lazy require to avoid circular dependency at module load time
|
||||
const { getCoordinatorSystemPrompt } =
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
require('../coordinator/coordinatorMode.js') as typeof import('../coordinator/coordinatorMode.js')
|
||||
return asSystemPrompt([
|
||||
getCoordinatorSystemPrompt(),
|
||||
...(appendSystemPrompt ? [appendSystemPrompt] : []),
|
||||
])
|
||||
}
|
||||
|
||||
const agentSystemPrompt = mainThreadAgentDefinition
|
||||
? isBuiltInAgent(mainThreadAgentDefinition)
|
||||
? mainThreadAgentDefinition.getSystemPrompt({
|
||||
toolUseContext: { options: toolUseContext.options },
|
||||
})
|
||||
: mainThreadAgentDefinition.getSystemPrompt()
|
||||
: undefined
|
||||
|
||||
// Log agent memory loaded event for main loop agents
|
||||
if (mainThreadAgentDefinition?.memory) {
|
||||
logEvent('tengu_agent_memory_loaded', {
|
||||
...(process.env.USER_TYPE === 'ant' && {
|
||||
agent_type:
|
||||
mainThreadAgentDefinition.agentType as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
}),
|
||||
scope:
|
||||
mainThreadAgentDefinition.memory as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
source:
|
||||
'main-thread' as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
})
|
||||
}
|
||||
|
||||
// In proactive mode, agent instructions are appended to the default prompt
|
||||
// rather than replacing it. The proactive default prompt is already lean
|
||||
// (autonomous agent identity + memory + env + proactive section), and agents
|
||||
// add domain-specific behavior on top — same pattern as teammates.
|
||||
if (
|
||||
agentSystemPrompt &&
|
||||
(feature('PROACTIVE') || feature('KAIROS')) &&
|
||||
isProactiveActive_SAFE_TO_CALL_ANYWHERE()
|
||||
) {
|
||||
return asSystemPrompt([
|
||||
...defaultSystemPrompt,
|
||||
`\n# Custom Agent Instructions\n${agentSystemPrompt}`,
|
||||
...(appendSystemPrompt ? [appendSystemPrompt] : []),
|
||||
])
|
||||
}
|
||||
|
||||
return asSystemPrompt([
|
||||
...(agentSystemPrompt
|
||||
? [agentSystemPrompt]
|
||||
: customSystemPrompt
|
||||
? [customSystemPrompt]
|
||||
: defaultSystemPrompt),
|
||||
...(appendSystemPrompt ? [appendSystemPrompt] : []),
|
||||
])
|
||||
}
|
||||
Reference in New Issue
Block a user