praxis-agent 0.28.0 → 0.30.0

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.
@@ -208,6 +208,7 @@ export declare class ClaudeSessionService {
208
208
  private applyPermissionUpdates;
209
209
  close(): Promise<void>;
210
210
  transitionHookSession(sessionId: string, reason: Exclude<HookSessionEndReason, 'other'>): Promise<void>;
211
+ reloadContextResources(sessionId: string): void;
211
212
  createHostedToolRegistry(sessionId: string): ToolRegistry;
212
213
  run(prompt: string, signal?: AbortSignal, sessionId?: string, name?: string, images?: readonly ModelImage[], documents?: readonly ModelDocument[]): Promise<SessionRunResult>;
213
214
  runShell(command: string, signal?: AbortSignal, sessionId?: string, name?: string): Promise<SessionRunResult>;
@@ -756,6 +756,16 @@ export class ClaudeSessionService {
756
756
  }
757
757
  async transitionHookSession(sessionId, reason) {
758
758
  await this.hookLifecycle.transition(sessionId, reason);
759
+ this.options.contextAssembler?.invalidate?.({
760
+ lifecycleId: sessionId,
761
+ reason: reason === 'resume' ? 'restore' : 'clear',
762
+ });
763
+ }
764
+ reloadContextResources(sessionId) {
765
+ this.options.contextAssembler?.invalidate?.({
766
+ lifecycleId: sessionId,
767
+ reason: 'resource-reload',
768
+ });
759
769
  }
760
770
  createHostedToolRegistry(sessionId) {
761
771
  const baseTools = this.options.tools;
@@ -996,6 +1006,7 @@ export class ClaudeSessionService {
996
1006
  }
997
1007
  const assembledContext = await this.options.contextAssembler?.assemble({
998
1008
  cwd: this.activeCwd(),
1009
+ lifecycleId: activeSessionId,
999
1010
  });
1000
1011
  const messages = [
1001
1012
  ...(assembledContext?.systemMessages ?? []),
@@ -1106,13 +1117,18 @@ export class ClaudeSessionService {
1106
1117
  const agent = this.resolveAgent(agentName);
1107
1118
  const provider = this.providerForAgent(agent);
1108
1119
  this.activeProvider = provider;
1120
+ const agentSystem = await this.mainAgentSystemPrompt(agent);
1109
1121
  const assembledContext = await this.options.contextAssembler?.assemble({
1110
1122
  cwd: this.activeCwd(),
1123
+ lifecycleId: sessionId,
1124
+ ...(agentSystem ? { mode: 'agent', baseSystemPrompt: agentSystem } : {}),
1111
1125
  });
1112
- const agentSystem = await this.mainAgentSystemPrompt(agent);
1113
- const assembledSystemMessages = this.assembledSystemMessages(agent, assembledContext?.systemMessages ?? []);
1126
+ const hasPromptManifest = assembledContext?.promptSections !== undefined;
1127
+ const assembledSystemMessages = hasPromptManifest
1128
+ ? (assembledContext?.systemMessages ?? [])
1129
+ : this.assembledSystemMessages(agent, assembledContext?.systemMessages ?? []);
1114
1130
  const contextMessages = [
1115
- ...(agentSystem
1131
+ ...(!hasPromptManifest && agentSystem
1116
1132
  ? [{ role: 'system', content: agentSystem }]
1117
1133
  : []),
1118
1134
  ...assembledSystemMessages,
@@ -1410,12 +1426,22 @@ export class ClaudeSessionService {
1410
1426
  this.sessionCwds.set(sessionId, cwd);
1411
1427
  this.runtimeCwd = cwd;
1412
1428
  this.options.workspace?.setCwd(cwd);
1429
+ this.options.contextAssembler?.invalidate?.({
1430
+ lifecycleId: sessionId,
1431
+ reason: 'cwd',
1432
+ });
1413
1433
  return cwd;
1414
1434
  }
1415
1435
  this.runtimeCwd = cwd;
1416
1436
  this.options.workspace?.setCwd(cwd);
1417
1437
  if (sessionId)
1418
1438
  this.sessionCwds.set(sessionId, cwd);
1439
+ if (sessionId) {
1440
+ this.options.contextAssembler?.invalidate?.({
1441
+ lifecycleId: sessionId,
1442
+ reason: 'cwd',
1443
+ });
1444
+ }
1419
1445
  return cwd;
1420
1446
  }
1421
1447
  async recordCdUsage(sessionId) {
@@ -1791,6 +1817,10 @@ export class ClaudeSessionService {
1791
1817
  if (result.status === 'conflict') {
1792
1818
  throw new Error('Generated Claude fork session already exists');
1793
1819
  }
1820
+ this.options.contextAssembler?.invalidate?.({
1821
+ lifecycleId: sessionId,
1822
+ reason: 'fork',
1823
+ });
1794
1824
  return { sessionId, parentSessionId };
1795
1825
  }
1796
1826
  async ensureFork(parentSessionId, sessionId, checkpoint) {
@@ -1799,8 +1829,13 @@ export class ClaudeSessionService {
1799
1829
  const expected = await this.nativeForkEntries(parentSessionId, sessionId, checkpoint?.resumeSessionAt, checkpoint?.entryCount);
1800
1830
  const target = this.store(sessionId);
1801
1831
  const created = await target.create(expected);
1802
- if (created.status === 'created')
1832
+ if (created.status === 'created') {
1833
+ this.options.contextAssembler?.invalidate?.({
1834
+ lifecycleId: sessionId,
1835
+ reason: 'fork',
1836
+ });
1803
1837
  return { sessionId, parentSessionId };
1838
+ }
1804
1839
  const existing = await target.withLease((lease) => lease.load());
1805
1840
  if (existing.status === 'conflict') {
1806
1841
  throw new Error(`Claude transcript fork conflict: ${existing.reason}`);
@@ -1810,6 +1845,10 @@ export class ClaudeSessionService {
1810
1845
  JSON.stringify(entry))) {
1811
1846
  throw new Error('Claude handoff target is not the expected native fork');
1812
1847
  }
1848
+ this.options.contextAssembler?.invalidate?.({
1849
+ lifecycleId: sessionId,
1850
+ reason: 'fork',
1851
+ });
1813
1852
  return { sessionId, parentSessionId };
1814
1853
  }
1815
1854
  async nativeForkEntries(parentSessionId, sessionId, resumeSessionAt, sourceEntryCount) {
@@ -2442,6 +2481,10 @@ export class ClaudeSessionService {
2442
2481
  currentTurnToolCalls += 1;
2443
2482
  const transition = this.worktreeManager?.consumeTransition(call.id);
2444
2483
  if (transition) {
2484
+ this.options.contextAssembler?.invalidate?.({
2485
+ lifecycleId: sessionId,
2486
+ reason: 'worktree',
2487
+ });
2445
2488
  const stateEntry = {
2446
2489
  type: 'worktree-state',
2447
2490
  worktreeSession: transition.state,
@@ -2584,29 +2627,83 @@ export class ClaudeSessionService {
2584
2627
  let planModeMessage;
2585
2628
  let sessionMemoryMessage = null;
2586
2629
  let contextMessages = [];
2630
+ let stableSystemMessageCount;
2587
2631
  const refreshRuntimeContext = async () => {
2588
- assembledContext = await this.options.contextAssembler?.assemble({
2589
- cwd: this.activeCwd(),
2590
- });
2591
2632
  agentSystem = await this.mainAgentSystemPrompt(agent);
2592
- const assembledSystemMessages = this.assembledSystemMessages(agent, assembledContext?.systemMessages ?? []);
2593
2633
  planModeMessage =
2594
2634
  this.options.interactiveTools?.contextMessage(sessionId);
2595
2635
  sessionMemoryMessage = sessionMemory
2596
2636
  ? this.sessionMemoryMessage(await sessionMemory.summary())
2597
2637
  : null;
2598
- contextMessages = [
2638
+ const additionalSections = [
2639
+ ...(planModeMessage
2640
+ ? [
2641
+ {
2642
+ id: 'plan-mode',
2643
+ placement: 'system',
2644
+ stability: 'volatile',
2645
+ content: planModeMessage,
2646
+ },
2647
+ ]
2648
+ : []),
2649
+ ...(sessionMemoryMessage
2650
+ ? [
2651
+ {
2652
+ id: 'session-memory',
2653
+ placement: 'system',
2654
+ stability: 'volatile',
2655
+ content: sessionMemoryMessage,
2656
+ },
2657
+ ]
2658
+ : []),
2659
+ ...(this.options.brief
2660
+ ? [
2661
+ {
2662
+ id: 'brief-output',
2663
+ placement: 'system',
2664
+ stability: 'volatile',
2665
+ content: CLAUDE_USER_MESSAGE_PROMPT,
2666
+ },
2667
+ ]
2668
+ : []),
2669
+ ...(this.options.structuredOutputSchema
2670
+ ? [
2671
+ {
2672
+ id: 'structured-output',
2673
+ placement: 'system',
2674
+ stability: 'volatile',
2675
+ content: 'You MUST call StructuredOutput exactly once at the end with a value matching the requested JSON Schema.',
2676
+ },
2677
+ ]
2678
+ : []),
2679
+ ];
2680
+ assembledContext = await this.options.contextAssembler?.assemble({
2681
+ cwd: this.activeCwd(),
2682
+ lifecycleId: sessionId,
2599
2683
  ...(agentSystem
2684
+ ? { mode: 'agent', baseSystemPrompt: agentSystem }
2685
+ : {}),
2686
+ additionalSections,
2687
+ });
2688
+ const hasPromptManifest = assembledContext?.promptSections !== undefined;
2689
+ stableSystemMessageCount = hasPromptManifest
2690
+ ? assembledContext?.stableSystemSectionCount
2691
+ : undefined;
2692
+ const assembledSystemMessages = hasPromptManifest
2693
+ ? (assembledContext?.systemMessages ?? [])
2694
+ : this.assembledSystemMessages(agent, assembledContext?.systemMessages ?? []);
2695
+ contextMessages = [
2696
+ ...(!hasPromptManifest && agentSystem
2600
2697
  ? [{ role: 'system', content: agentSystem }]
2601
2698
  : []),
2602
2699
  ...assembledSystemMessages,
2603
- ...(planModeMessage
2700
+ ...(!hasPromptManifest && planModeMessage
2604
2701
  ? [{ role: 'system', content: planModeMessage }]
2605
2702
  : []),
2606
- ...(sessionMemoryMessage
2703
+ ...(!hasPromptManifest && sessionMemoryMessage
2607
2704
  ? [{ role: 'system', content: sessionMemoryMessage }]
2608
2705
  : []),
2609
- ...(this.options.brief
2706
+ ...(!hasPromptManifest && this.options.brief
2610
2707
  ? [
2611
2708
  {
2612
2709
  role: 'system',
@@ -2614,7 +2711,7 @@ export class ClaudeSessionService {
2614
2711
  },
2615
2712
  ]
2616
2713
  : []),
2617
- ...(this.options.structuredOutputSchema
2714
+ ...(!hasPromptManifest && this.options.structuredOutputSchema
2618
2715
  ? [
2619
2716
  {
2620
2717
  role: 'system',
@@ -2915,6 +3012,10 @@ export class ClaudeSessionService {
2915
3012
  if (outcome)
2916
3013
  await recordHookOutcome(outcome);
2917
3014
  }
3015
+ this.options.contextAssembler?.invalidate?.({
3016
+ lifecycleId: sessionId,
3017
+ reason: 'compact',
3018
+ });
2918
3019
  await refreshRuntimeContext();
2919
3020
  this.options.eventSink?.({
2920
3021
  type: 'compact-boundary',
@@ -3086,6 +3187,9 @@ export class ClaudeSessionService {
3086
3187
  ...contextMessages,
3087
3188
  ...injectTurnContext(projectClaudeModelMessages(snapshot.entries)),
3088
3189
  ],
3190
+ ...(stableSystemMessageCount === undefined
3191
+ ? {}
3192
+ : { stableSystemMessageCount }),
3089
3193
  cwd: this.activeCwd(),
3090
3194
  toolResultDirectory,
3091
3195
  observer,
@@ -3099,6 +3203,12 @@ export class ClaudeSessionService {
3099
3203
  : {}),
3100
3204
  reloadMessages: async () => {
3101
3205
  await compactIfNeeded([], currentTurnUserMessages ?? []);
3206
+ if (stableSystemMessageCount === undefined) {
3207
+ delete runtimeRequest.stableSystemMessageCount;
3208
+ }
3209
+ else {
3210
+ runtimeRequest.stableSystemMessageCount = stableSystemMessageCount;
3211
+ }
3102
3212
  return [
3103
3213
  ...contextMessages,
3104
3214
  ...injectTurnContext(projectClaudeModelMessages(snapshot.entries)),
@@ -3213,6 +3323,12 @@ export class ClaudeSessionService {
3213
3323
  ...contextMessages,
3214
3324
  ...injectTurnContext(projectClaudeModelMessages(snapshot.entries)),
3215
3325
  ];
3326
+ if (stableSystemMessageCount === undefined) {
3327
+ delete runtimeRequest.stableSystemMessageCount;
3328
+ }
3329
+ else {
3330
+ runtimeRequest.stableSystemMessageCount = stableSystemMessageCount;
3331
+ }
3216
3332
  try {
3217
3333
  result = await attemptMainTurn();
3218
3334
  }
@@ -1493,10 +1493,16 @@ export class ClaudeSubagentExecutor {
1493
1493
  const assembleMessages = async () => {
1494
1494
  const assembledContext = await this.options.contextAssembler?.assemble({
1495
1495
  cwd,
1496
+ lifecycleId: options.agentId,
1497
+ mode: 'subagent',
1498
+ baseSystemPrompt: system,
1496
1499
  });
1500
+ const composedSubagentPolicy = assembledContext?.promptSections?.some((section) => section.id === 'subagent-policy');
1497
1501
  const messages = [
1498
1502
  ...(assembledContext?.systemMessages ?? []),
1499
- { role: 'system', content: system },
1503
+ ...(composedSubagentPolicy
1504
+ ? []
1505
+ : [{ role: 'system', content: system }]),
1500
1506
  ...injectFirstUserMessageContext(projectClaudeModelMessages(snapshot.entries), assembledContext?.firstUserMessageContext),
1501
1507
  ...preloadedSkills,
1502
1508
  ];
@@ -30,6 +30,14 @@ const WORKER_RUNTIME_ENVIRONMENT = [
30
30
  'PRAXIS_MAX_OUTPUT_TOKENS',
31
31
  'PRAXIS_ANTHROPIC_VERSION',
32
32
  'PRAXIS_ANTHROPIC_WEB_SEARCH',
33
+ 'PRAXIS_ANTHROPIC_PROMPT_CACHING',
34
+ 'PRAXIS_ANTHROPIC_PROMPT_CACHE_TTL',
35
+ 'DISABLE_PROMPT_CACHING',
36
+ 'DISABLE_PROMPT_CACHING_HAIKU',
37
+ 'DISABLE_PROMPT_CACHING_SONNET',
38
+ 'DISABLE_PROMPT_CACHING_OPUS',
39
+ 'ENABLE_PROMPT_CACHING_1H',
40
+ 'FORCE_PROMPT_CACHING_5M',
33
41
  'PRAXIS_CONTEXT_WINDOW_TOKENS',
34
42
  'PRAXIS_CONTEXT_RESERVE_TOKENS',
35
43
  'PRAXIS_PRICING_JSON',
@@ -39,6 +39,7 @@ import { writeFileAtomically } from './platform/atomic-write.js';
39
39
  import { detectInstalledClaudeVersion } from './platform/claude-version.js';
40
40
  import { redactSensitiveText, sensitiveEnvironmentValues, } from './platform/sensitive-data.js';
41
41
  import { AnthropicCompatibleProvider } from './providers/anthropic-compatible.js';
42
+ import { createAnthropicPromptCachePolicyResolver } from './providers/anthropic-prompt-cache.js';
42
43
  import { FallbackModelProvider } from './providers/fallback-provider.js';
43
44
  import { OpenAICompatibleProvider } from './providers/openai-compatible.js';
44
45
  import { parseContextEnvironment, parseProviderEnvironment, } from './providers/environment.js';
@@ -89,34 +90,37 @@ function fileResourceHeaders(environment, providerEnvironment, credential) {
89
90
  : {}),
90
91
  };
91
92
  }
92
- function createProviderForModel(apiKey, providerEnvironment, context, controls, explicitThinkingControls) {
93
+ function createProviderForModel({ apiKey, environment, dataPlane, provider, context, controls, explicitThinkingControls, }) {
94
+ const resolvePromptCachePolicy = createAnthropicPromptCachePolicyResolver(environment, dataPlane);
93
95
  return (selectedModel) => {
94
96
  const providerOptions = {
95
97
  apiKey,
96
98
  model: selectedModel,
97
- baseUrl: providerEnvironment.baseUrl,
99
+ baseUrl: provider.baseUrl,
98
100
  ...('contextWindowTokens' in context
99
101
  ? { contextWindowTokens: context.contextWindowTokens }
100
102
  : {}),
101
103
  };
102
- return providerEnvironment.provider === 'anthropic'
104
+ return provider.provider === 'anthropic'
103
105
  ? new AnthropicCompatibleProvider({
104
106
  ...providerOptions,
107
+ promptCaching: resolvePromptCachePolicy({
108
+ baseUrl: provider.baseUrl,
109
+ model: selectedModel,
110
+ }),
105
111
  thinking: {
106
112
  mode: controls.thinking ?? 'enabled',
107
113
  ...(controls.maxThinkingTokens === undefined
108
114
  ? {}
109
115
  : { maxTokens: controls.maxThinkingTokens }),
110
116
  },
111
- ...('maxOutputTokens' in providerEnvironment
112
- ? { maxOutputTokens: providerEnvironment.maxOutputTokens }
113
- : {}),
114
- ...('anthropicVersion' in providerEnvironment
115
- ? { anthropicVersion: providerEnvironment.anthropicVersion }
117
+ ...('maxOutputTokens' in provider
118
+ ? { maxOutputTokens: provider.maxOutputTokens }
116
119
  : {}),
117
- ...('webSearch' in providerEnvironment
118
- ? { webSearch: providerEnvironment.webSearch }
120
+ ...('anthropicVersion' in provider
121
+ ? { anthropicVersion: provider.anthropicVersion }
119
122
  : {}),
123
+ ...('webSearch' in provider ? { webSearch: provider.webSearch } : {}),
120
124
  })
121
125
  : new OpenAICompatibleProvider({
122
126
  ...providerOptions,
@@ -245,6 +249,8 @@ Provider environment:
245
249
  PRAXIS_PROVIDER=openai|anthropic, PRAXIS_API_KEY, PRAXIS_MODEL
246
250
  PRAXIS_BASE_URL, PRAXIS_MAX_OUTPUT_TOKENS, PRAXIS_ANTHROPIC_VERSION
247
251
  PRAXIS_ANTHROPIC_WEB_SEARCH=true|false
252
+ PRAXIS_ANTHROPIC_PROMPT_CACHING=true|false
253
+ PRAXIS_ANTHROPIC_PROMPT_CACHE_TTL=5m|1h
248
254
  PRAXIS_CONTEXT_WINDOW_TOKENS, PRAXIS_CONTEXT_RESERVE_TOKENS
249
255
  `;
250
256
  const AGENTS_HELP = `Usage: praxis agents [options]
@@ -802,12 +808,6 @@ const createDefaultService = async ({ eventSink, requireProvider, hooksOnly = fa
802
808
  ? {}
803
809
  : { permissionMode: interactivePermissionMode }),
804
810
  }, cwd);
805
- const effectiveAppendSystemPrompt = [
806
- runtimeSettingsPrompt,
807
- cli.appendSystemPrompt,
808
- ]
809
- .filter((value) => value !== undefined)
810
- .join('\n');
811
811
  const debug = cli.debug !== undefined || cli.debugFile !== undefined
812
812
  ? createCliDebugSink(eventSink, {
813
813
  cwd,
@@ -843,7 +843,15 @@ const createDefaultService = async ({ eventSink, requireProvider, hooksOnly = fa
843
843
  if (!providerEnvironment) {
844
844
  throw new Error('Provider environment is unavailable');
845
845
  }
846
- providerForModel = createProviderForModel(apiKey, providerEnvironment, context, cli, controls);
846
+ providerForModel = createProviderForModel({
847
+ apiKey,
848
+ environment: runtimeEnvironment,
849
+ dataPlane,
850
+ provider: providerEnvironment,
851
+ context,
852
+ controls: cli,
853
+ explicitThinkingControls: controls,
854
+ });
847
855
  const createProvider = providerForModel;
848
856
  providerForMainModel = (primaryModel) => {
849
857
  const models = [primaryModel, ...(cli.fallbackModels ?? [])].filter((candidate, index, all) => all.indexOf(candidate) === index);
@@ -1175,6 +1183,7 @@ const createDefaultService = async ({ eventSink, requireProvider, hooksOnly = fa
1175
1183
  });
1176
1184
  return filterDisabledMcpResources(candidates, await management.disabled());
1177
1185
  };
1186
+ let contextAssembler;
1178
1187
  const mcpTools = await ClaudeMcpToolRegistry.connect({
1179
1188
  base: simpleMode
1180
1189
  ? localTools
@@ -1219,6 +1228,7 @@ const createDefaultService = async ({ eventSink, requireProvider, hooksOnly = fa
1219
1228
  configRoot,
1220
1229
  onWarning: (message) => runtimeEventSink({ type: 'warning', message }),
1221
1230
  onPromptsChanged: (prompts) => extensions.setMcpPrompts(prompts),
1231
+ onInstructionsChanged: () => contextAssembler?.invalidate({ reason: 'tool-pool' }),
1222
1232
  authenticateServer: async (name) => {
1223
1233
  const record = await new ClaudeMcpManagement({
1224
1234
  dataPlane,
@@ -1374,6 +1384,54 @@ const createDefaultService = async ({ eventSink, requireProvider, hooksOnly = fa
1374
1384
  },
1375
1385
  })
1376
1386
  : undefined;
1387
+ contextAssembler = new ClaudeContextAssembler({
1388
+ loadResources: loadContextResources,
1389
+ loadDynamicContext: (runtimeCwd = workspace.cwd()) => loadClaudeDynamicContext({
1390
+ cwd: runtimeCwd,
1391
+ ...(memoryDirectory ? { memoryDirectory } : {}),
1392
+ }),
1393
+ loadMcpInstructions: async () => mcpTools.instructions(),
1394
+ loadSessionGuidance: async () => {
1395
+ const toolNames = [
1396
+ ...new Set([
1397
+ ...filteredTools.definitions().map((definition) => definition.name),
1398
+ ...selectedTaskRuntimeTools,
1399
+ ...selectedScheduledTools,
1400
+ ...selectedWorkflowTools,
1401
+ ...selectedWorktreeTools,
1402
+ ...selectedInteractiveTools,
1403
+ ...(enableSubagents ? selectedAgentTools : []),
1404
+ ]),
1405
+ ].sort();
1406
+ const skillNames = extensions
1407
+ .modelInvocableSkills()
1408
+ .map((skill) => skill.name)
1409
+ .sort();
1410
+ if (toolNames.length === 0 &&
1411
+ skillNames.length === 0 &&
1412
+ runtimeSettingsPrompt === undefined)
1413
+ return undefined;
1414
+ return [
1415
+ '# Session capabilities',
1416
+ ...(toolNames.length > 0
1417
+ ? [`Enabled tools: ${toolNames.join(', ')}`]
1418
+ : []),
1419
+ ...(skillNames.length > 0
1420
+ ? [`Model-invocable skills: ${skillNames.join(', ')}`]
1421
+ : []),
1422
+ 'Use a capability only when it directly helps complete the request, and follow its declared input contract.',
1423
+ ...(runtimeSettingsPrompt ? ['', runtimeSettingsPrompt] : []),
1424
+ ].join('\n');
1425
+ },
1426
+ excludeDynamicSystemPromptSections: cli.excludeDynamicSystemPromptSections,
1427
+ ...(cli.systemPrompt === undefined
1428
+ ? {}
1429
+ : { systemPrompt: cli.systemPrompt }),
1430
+ ...(cli.appendSystemPrompt
1431
+ ? { appendSystemPrompt: cli.appendSystemPrompt }
1432
+ : {}),
1433
+ ...(simpleMode ? { bare: true } : {}),
1434
+ });
1377
1435
  const service = new ClaudeSessionService({
1378
1436
  ...options,
1379
1437
  provider: hostedToolProvider,
@@ -1409,20 +1467,7 @@ const createDefaultService = async ({ eventSink, requireProvider, hooksOnly = fa
1409
1467
  ...(interactiveTools ? { interactiveTools } : {}),
1410
1468
  ...(hooks ? { hooks } : {}),
1411
1469
  ...(selectedMainAgent ? { agent: selectedMainAgent } : {}),
1412
- contextAssembler: new ClaudeContextAssembler({
1413
- loadResources: loadContextResources,
1414
- loadDynamicContext: (runtimeCwd = workspace.cwd()) => loadClaudeDynamicContext({
1415
- cwd: runtimeCwd,
1416
- ...(memoryDirectory ? { memoryDirectory } : {}),
1417
- }),
1418
- excludeDynamicSystemPromptSections: cli.excludeDynamicSystemPromptSections,
1419
- ...(cli.systemPrompt === undefined
1420
- ? {}
1421
- : { systemPrompt: cli.systemPrompt }),
1422
- ...(effectiveAppendSystemPrompt
1423
- ? { appendSystemPrompt: effectiveAppendSystemPrompt }
1424
- : {}),
1425
- }),
1470
+ contextAssembler,
1426
1471
  conditionalRuleResolver: new ClaudeConditionalRuleResolver({
1427
1472
  loadResources: loadContextResources,
1428
1473
  }),
@@ -1674,7 +1719,16 @@ const createDefaultAutoModeCritic = async ({ model, dataPlane, configRoot, state
1674
1719
  if (!apiKey || !selectedModel) {
1675
1720
  throw new Error('PRAXIS_API_KEY and a model (--model or PRAXIS_MODEL) are required');
1676
1721
  }
1677
- return createProviderForModel(apiKey, parseProviderEnvironment(process.env), parseContextEnvironment(process.env), {}, {})(selectedModel);
1722
+ const providerEnvironment = parseProviderEnvironment(process.env);
1723
+ return createProviderForModel({
1724
+ apiKey,
1725
+ environment: process.env,
1726
+ dataPlane: resolvedDataPlane,
1727
+ provider: providerEnvironment,
1728
+ context: parseContextEnvironment(process.env),
1729
+ controls: {},
1730
+ explicitThinkingControls: {},
1731
+ })(selectedModel);
1678
1732
  };
1679
1733
  const defaultPluginEvalRuntimeFactory = {
1680
1734
  create: async (options) => {
@@ -1774,7 +1828,16 @@ const defaultPluginEvalJudge = {
1774
1828
  const apiKey = environment.PRAXIS_API_KEY;
1775
1829
  if (!apiKey)
1776
1830
  throw new Error('PRAXIS_API_KEY is required for paid eval graders');
1777
- const provider = createProviderForModel(apiKey, parseProviderEnvironment(environment), parseContextEnvironment(environment), {}, {})(model);
1831
+ const providerEnvironment = parseProviderEnvironment(environment);
1832
+ const provider = createProviderForModel({
1833
+ apiKey,
1834
+ environment,
1835
+ dataPlane: resolveDataPlane(environment),
1836
+ provider: providerEnvironment,
1837
+ context: parseContextEnvironment(environment),
1838
+ controls: {},
1839
+ explicitThinkingControls: {},
1840
+ })(model);
1778
1841
  const prompt = `You are an eval judge. Return only JSON matching {"passed":boolean,"explanation":string}.
1779
1842
 
1780
1843
  Criteria:
@@ -1,12 +1,20 @@
1
- import type { AssembledContext, ContextAssembler } from '../../core/context.js';
1
+ import type { AssembledContext, ContextAssembler, ContextAssemblyOptions, ContextInvalidationOptions } from '../../core/context.js';
2
2
  import { type ClaudeDynamicContextSections } from './dynamic-context.js';
3
3
  import type { ClaudeContextResources, ClaudeConditionalRule } from './shared-resources.js';
4
4
  export interface ClaudeContextAssemblerOptions {
5
5
  loadResources(cwd?: string): Promise<ClaudeContextResources>;
6
6
  loadDynamicContext?(cwd?: string): Promise<ClaudeDynamicContextSections>;
7
+ loadMcpInstructions?(): Promise<readonly ClaudeMcpInstruction[]>;
8
+ loadSessionGuidance?(): Promise<string | undefined>;
7
9
  excludeDynamicSystemPromptSections?: boolean;
8
10
  systemPrompt?: string;
9
11
  appendSystemPrompt?: string;
12
+ bare?: boolean;
13
+ now?(): Date;
14
+ }
15
+ export interface ClaudeMcpInstruction {
16
+ server: string;
17
+ instructions: string;
10
18
  }
11
19
  export type ClaudeConditionalRuleResolverOptions = ClaudeContextAssemblerOptions;
12
20
  export declare class ClaudeConditionalRuleResolver {
@@ -16,9 +24,16 @@ export declare class ClaudeConditionalRuleResolver {
16
24
  }
17
25
  export declare class ClaudeContextAssembler implements ContextAssembler {
18
26
  private readonly options;
27
+ private readonly composer;
28
+ private readonly snapshots;
19
29
  constructor(options: ClaudeContextAssemblerOptions);
20
- assemble(options?: {
21
- cwd?: string;
22
- }): Promise<AssembledContext>;
30
+ assemble(options?: ContextAssemblyOptions): Promise<AssembledContext>;
31
+ invalidate(options: ContextInvalidationOptions): void;
32
+ private snapshot;
33
+ private loadResources;
34
+ private loadDynamicContext;
35
+ private loadMcpInstructions;
36
+ private loadSessionGuidance;
37
+ private currentDate;
23
38
  }
24
39
  //# sourceMappingURL=context.d.ts.map