@myagentroam/agent 0.11.6 → 0.11.8

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.
@@ -317,7 +317,12 @@ export class AnthropicMessagesAdapter {
317
317
  throw new MarAgentError('MAR_AGENT_MODEL_PROTOCOL_ERROR', 'Anthropic returned an invalid or oversized native thinking block.');
318
318
  thinkingBytes += Buffer.byteLength(JSON.stringify(item));
319
319
  assertAnthropicThinkingBudget(thinkingBytes);
320
- yield observeModelStreamEvent({ type: 'response.item', provider: 'ANTHROPIC_MESSAGES', item }, modelStreamEventObservedAt(raw));
320
+ yield observeModelStreamEvent({
321
+ type: 'response.item',
322
+ provider: 'ANTHROPIC_MESSAGES',
323
+ contextKind: 'private',
324
+ item
325
+ }, modelStreamEventObservedAt(raw));
321
326
  }
322
327
  if (block.type === 'thinking' && block.text.trim())
323
328
  yield observeModelStreamEvent({
@@ -149,6 +149,7 @@ export type ModelEvent = {
149
149
  } | {
150
150
  type: 'response.item';
151
151
  provider: 'OPENAI_RESPONSES' | 'ANTHROPIC_MESSAGES';
152
+ contextKind?: ModelMessage['contextKind'];
152
153
  item: Record<string, unknown>;
153
154
  } | {
154
155
  type: 'text.delta';
@@ -0,0 +1,3 @@
1
+ import type { ModelMessage } from './contracts.js';
2
+ /** Interpret only the existing native context record shapes and their model ownership. */
3
+ export declare function restoreNativeModelContext(payload: Record<string, unknown>, activeModelId?: string): ModelMessage | undefined;
@@ -0,0 +1,44 @@
1
+ import { anthropicThinkingBlock } from './anthropic-thinking.js';
2
+ /** Interpret only the existing native context record shapes and their model ownership. */
3
+ export function restoreNativeModelContext(payload, activeModelId) {
4
+ const modelId = typeof payload.providerModelId === 'string' && payload.providerModelId.length > 0
5
+ ? payload.providerModelId
6
+ : undefined;
7
+ const contextKind = nativeContextKind(payload.contextKind);
8
+ if (payload.provider === 'ANTHROPIC_MESSAGES') {
9
+ const item = anthropicThinkingBlock(payload.item);
10
+ return item && modelId
11
+ ? {
12
+ role: 'provider',
13
+ content: '',
14
+ provider: 'ANTHROPIC_MESSAGES',
15
+ providerModelId: modelId,
16
+ contextKind: contextKind ?? 'private',
17
+ item
18
+ }
19
+ : undefined;
20
+ }
21
+ if (payload.provider !== 'OPENAI_RESPONSES' ||
22
+ !payload.item ||
23
+ typeof payload.item !== 'object' ||
24
+ Array.isArray(payload.item))
25
+ return undefined;
26
+ const restoredModelId = modelId ?? activeModelId;
27
+ return {
28
+ role: 'provider',
29
+ content: '',
30
+ provider: 'OPENAI_RESPONSES',
31
+ ...(restoredModelId === undefined ? {} : { providerModelId: restoredModelId }),
32
+ ...(contextKind === undefined ? {} : { contextKind }),
33
+ item: payload.item
34
+ };
35
+ }
36
+ function nativeContextKind(value) {
37
+ return value === 'environment' ||
38
+ value === 'private' ||
39
+ value === 'contextual' ||
40
+ value === 'summary' ||
41
+ value === 'compact_control'
42
+ ? value
43
+ : undefined;
44
+ }
@@ -0,0 +1,17 @@
1
+ import { type MarAgentModelConfiguration, type MarAgentReasoningEffort } from './configuration.js';
2
+ import type { ModelMessage } from './contracts.js';
3
+ /** Resolve request effort and native updates without owning their persistence or timing. */
4
+ export declare function prepareModelConfiguration(model: Pick<MarAgentModelConfiguration, 'id' | 'protocol' | 'responsesConfigurationUpdates' | 'codexCredential'>, effort: MarAgentReasoningEffort, context: {
5
+ readonly baselineEffort: MarAgentReasoningEffort | undefined;
6
+ readonly messages: readonly ModelMessage[];
7
+ readonly checkpointAdopted?: false;
8
+ } | {
9
+ readonly checkpointAdopted: true;
10
+ }): {
11
+ readonly requestReasoningEffort?: MarAgentReasoningEffort;
12
+ readonly updates: readonly ModelMessage[];
13
+ readonly contextProjection: {
14
+ readonly modelProtocol: MarAgentModelConfiguration['protocol'];
15
+ readonly responsesConfigurationUpdates: boolean;
16
+ };
17
+ };
@@ -0,0 +1,47 @@
1
+ import { marAgentReasoningEffortSchema, usesResponsesConfigurationUpdates } from './configuration.js';
2
+ /** Resolve request effort and native updates without owning their persistence or timing. */
3
+ export function prepareModelConfiguration(model, effort, context) {
4
+ const useUpdates = usesResponsesConfigurationUpdates(model);
5
+ const contextProjection = {
6
+ modelProtocol: model.protocol,
7
+ responsesConfigurationUpdates: useUpdates
8
+ };
9
+ if (context.checkpointAdopted)
10
+ return { requestReasoningEffort: effort, updates: [], contextProjection };
11
+ if (!useUpdates)
12
+ return { updates: [], contextProjection };
13
+ const requestReasoningEffort = context.baselineEffort ?? effort;
14
+ const effectiveEffort = context.baselineEffort === undefined
15
+ ? requestReasoningEffort
16
+ : (lastConfigurationEffort(context.messages, model.id) ?? requestReasoningEffort);
17
+ return {
18
+ requestReasoningEffort,
19
+ contextProjection,
20
+ updates: effectiveEffort === effort
21
+ ? []
22
+ : [
23
+ {
24
+ role: 'provider',
25
+ content: '',
26
+ provider: 'OPENAI_RESPONSES',
27
+ providerModelId: model.id,
28
+ item: { type: 'configuration_update', reasoning: { effort } }
29
+ }
30
+ ]
31
+ };
32
+ }
33
+ function lastConfigurationEffort(messages, modelId) {
34
+ for (let index = messages.length - 1; index >= 0; index--) {
35
+ const message = messages[index];
36
+ if (message.role !== 'provider' ||
37
+ message.provider !== 'OPENAI_RESPONSES' ||
38
+ message.providerModelId !== modelId ||
39
+ message.item?.type !== 'configuration_update')
40
+ continue;
41
+ const reasoning = message.item.reasoning;
42
+ const effort = marAgentReasoningEffortSchema.safeParse(reasoning?.effort);
43
+ if (effort.success)
44
+ return effort.data;
45
+ }
46
+ return undefined;
47
+ }
@@ -0,0 +1,4 @@
1
+ import type { MarAgentModelConfiguration } from './configuration.js';
2
+ import type { ClientToolDefinition } from './contracts.js';
3
+ /** Native Responses discovery carries deferred definitions in history, not the top-level catalog. */
4
+ export declare function projectModelRequestTools(model: Pick<MarAgentModelConfiguration, 'protocol'>, tools: readonly ClientToolDefinition[], residentNames: ReadonlySet<string>): readonly ClientToolDefinition[];
@@ -0,0 +1,6 @@
1
+ /** Native Responses discovery carries deferred definitions in history, not the top-level catalog. */
2
+ export function projectModelRequestTools(model, tools, residentNames) {
3
+ return model.protocol === 'OPENAI_RESPONSES'
4
+ ? tools.filter((tool) => residentNames.has(tool.name))
5
+ : tools;
6
+ }
@@ -1,4 +1,4 @@
1
- import { anthropicThinkingBlock } from '../../model/anthropic-thinking.js';
1
+ import { restoreNativeModelContext } from '../../model/native-context.js';
2
2
  import { appliedInputRecord } from '../../session/deferred-input.js';
3
3
  import { inputMetadataFromRecord } from '../../session/store/index.js';
4
4
  import { contextGcTargetKey, latestValidContextGcCheckpoint } from '../../session/context-gc-checkpoint.js';
@@ -227,34 +227,8 @@ export function restoreModelContext(payload, providerModelId) {
227
227
  ? { inputMode: payload.inputMode }
228
228
  : {})
229
229
  };
230
- if (payload.role === 'provider' && payload.provider === 'ANTHROPIC_MESSAGES') {
231
- const item = anthropicThinkingBlock(payload.item);
232
- const modelId = modelIdFromPayload(payload, 'providerModelId');
233
- return item && modelId
234
- ? {
235
- role: 'provider',
236
- provider: 'ANTHROPIC_MESSAGES',
237
- providerModelId: modelId,
238
- contextKind: 'private',
239
- content: '',
240
- item
241
- }
242
- : undefined;
243
- }
244
- if (payload.role === 'provider' &&
245
- payload.provider === 'OPENAI_RESPONSES' &&
246
- isRecord(payload.item)) {
247
- const restoredProviderModelId = modelIdFromPayload(payload, 'providerModelId') ?? providerModelId;
248
- return {
249
- role: 'provider',
250
- content: '',
251
- provider: 'OPENAI_RESPONSES',
252
- ...(restoredProviderModelId === undefined
253
- ? {}
254
- : { providerModelId: restoredProviderModelId }),
255
- item: payload.item
256
- };
257
- }
230
+ if (payload.role === 'provider')
231
+ return restoreNativeModelContext(payload, providerModelId);
258
232
  return undefined;
259
233
  }
260
234
  export function providerToolCallId(message) {
@@ -8,7 +8,6 @@ export interface AuthoritativeModelUsage {
8
8
  }
9
9
  export declare function latestModelUsage(records: readonly import('../../session/store/index.js').SessionRecord[], selectedModelId: string): AuthoritativeModelUsage | undefined;
10
10
  export declare function reasoningEffortBaseline(records: readonly import('../../session/store/index.js').SessionRecord[], modelId: string): MarAgentReasoningEffort | undefined;
11
- export declare function lastConfigurationEffort(messages: readonly ModelMessage[], modelId: string): MarAgentReasoningEffort | undefined;
12
11
  export declare function shouldUseNativeCompaction(input: {
13
12
  readonly estimatedRequestTokens: number;
14
13
  readonly contextWindowTokens: number;
@@ -82,21 +82,6 @@ export function reasoningEffortBaseline(records, modelId) {
82
82
  }
83
83
  return baseline;
84
84
  }
85
- export function lastConfigurationEffort(messages, modelId) {
86
- for (let index = messages.length - 1; index >= 0; index--) {
87
- const message = messages[index];
88
- if (message.role !== 'provider' ||
89
- message.provider !== 'OPENAI_RESPONSES' ||
90
- message.providerModelId !== modelId ||
91
- message.item?.type !== 'configuration_update')
92
- continue;
93
- const reasoning = message.item.reasoning;
94
- const effort = marAgentReasoningEffortSchema.safeParse(reasoning?.effort);
95
- if (effort.success)
96
- return effort.data;
97
- }
98
- return undefined;
99
- }
100
85
  export function shouldUseNativeCompaction(input) {
101
86
  if (input.estimatedRequestTokens <= input.contextWindowTokens)
102
87
  return true;
@@ -132,9 +132,7 @@ export class ExecutionLoop {
132
132
  content: '',
133
133
  provider: event.provider,
134
134
  providerModelId: input.model.id,
135
- ...(event.provider === 'ANTHROPIC_MESSAGES'
136
- ? { contextKind: 'private' }
137
- : {}),
135
+ ...(event.contextKind === undefined ? {} : { contextKind: event.contextKind }),
138
136
  item: event.item
139
137
  };
140
138
  messages.push(message);
@@ -9,5 +9,10 @@ export declare function resolveAgentModels(configurations: readonly MarAgentMode
9
9
  readonly credentialProviders: Set<ModelCredentialProvider>;
10
10
  };
11
11
  export declare function createModelTurnSession(adapter: ModelAdapter): ModelTurnSession;
12
+ /** Owns only one Execution's model turn and explicitly transferred adapters. */
13
+ export declare function createExecutionModelResources(activeAdapters: Set<ModelAdapter>): {
14
+ openTurn(adapter: ModelAdapter, ownsAdapter: boolean): ModelTurnSession;
15
+ close(): Promise<void>;
16
+ };
12
17
  export declare function closeModelAdapters(adapters: Iterable<ModelAdapter>): Promise<void>;
13
18
  export declare function addModelCredentialProviders(target: Set<ModelCredentialProvider>, configuration: MarAgentModelConfiguration): void;
@@ -51,6 +51,34 @@ export function createModelTurnSession(adapter) {
51
51
  close: () => turn.close()
52
52
  };
53
53
  }
54
+ /** Owns only one Execution's model turn and explicitly transferred adapters. */
55
+ export function createExecutionModelResources(activeAdapters) {
56
+ let turn;
57
+ const ownedAdapters = new Set();
58
+ return {
59
+ openTurn(adapter, ownsAdapter) {
60
+ if (ownsAdapter) {
61
+ ownedAdapters.add(adapter);
62
+ activeAdapters.add(adapter);
63
+ }
64
+ turn = createModelTurnSession(adapter);
65
+ return turn;
66
+ },
67
+ async close() {
68
+ await turn?.close().catch(() => undefined);
69
+ try {
70
+ await closeModelAdapters(ownedAdapters);
71
+ }
72
+ catch {
73
+ // Model cleanup must not replace the Execution result.
74
+ }
75
+ finally {
76
+ for (const adapter of ownedAdapters)
77
+ activeAdapters.delete(adapter);
78
+ }
79
+ }
80
+ };
81
+ }
54
82
  export async function closeModelAdapters(adapters) {
55
83
  const results = await Promise.allSettled([...new Set(adapters)].flatMap((adapter) => adapter.close === undefined ? [] : [adapter.close()]));
56
84
  const failure = results.find((result) => result.status === 'rejected');
@@ -0,0 +1,7 @@
1
+ import type { MarAgentModelConfiguration } from '../model/configuration.js';
2
+ import type { ClientToolDefinition, ModelMessage, ModelRequest } from '../model/contracts.js';
3
+ import { type ContextualWorldState } from '../runtime/context/world-state.js';
4
+ /** Assemble captured round values only. Admission, Hooks and publication belong to Session. */
5
+ export declare function prepareSessionModelRequest(candidate: ModelRequest, model: Pick<MarAgentModelConfiguration, 'protocol' | 'inputCapabilities'>, entries: ContextualWorldState['entries'], residentTools: readonly ClientToolDefinition[], autoPermission: boolean): ModelRequest;
6
+ /** The actual candidate and current Session view share the same side-effect-free projection. */
7
+ export declare function projectSessionRequestMessages(messages: readonly ModelMessage[], entries: ContextualWorldState['entries'], supportsImages: boolean, codeMode: boolean, autoPermission?: boolean): ModelMessage[];
@@ -0,0 +1,23 @@
1
+ import { projectModelRequestTools } from '../model/tool-declarations.js';
2
+ import { projectSmartCompactionMessage } from '../runtime/compaction/smart.js';
3
+ import { normalizeMessagesForModel } from '../runtime/context/normalize.js';
4
+ import { insertContextualWorldState } from '../runtime/context/world-state.js';
5
+ import { projectCodeModeSearchResult, projectCodeModeTools } from '../tools/code-mode/index.js';
6
+ import { projectPermissionTool } from '../tools/permissions.js';
7
+ /** Assemble captured round values only. Admission, Hooks and publication belong to Session. */
8
+ export function prepareSessionModelRequest(candidate, model, entries, residentTools, autoPermission) {
9
+ const codeMode = candidate.tools.some((tool) => tool.name === 'code_exec');
10
+ return {
11
+ ...candidate,
12
+ messages: projectSessionRequestMessages(candidate.messages, entries, model.inputCapabilities.includes('IMAGE'), codeMode, autoPermission),
13
+ tools: projectModelRequestTools(model, projectCodeModeTools(candidate.tools, residentTools), new Set(residentTools.map((tool) => tool.name)))
14
+ };
15
+ }
16
+ /** The actual candidate and current Session view share the same side-effect-free projection. */
17
+ export function projectSessionRequestMessages(messages, entries, supportsImages, codeMode, autoPermission = false) {
18
+ return normalizeMessagesForModel(insertContextualWorldState(messages, entries), {
19
+ supportsImages
20
+ }).map((message) => projectCodeModeSearchResult(autoPermission && message.toolSearchTools
21
+ ? { ...message, toolSearchTools: message.toolSearchTools.map(projectPermissionTool) }
22
+ : projectSmartCompactionMessage(message), codeMode));
23
+ }
@@ -7,7 +7,7 @@ import { ExtensionRequestSnapshots } from '../extensions/model-request.js';
7
7
  import { SessionInputCoordinator, type CoreSessionBackend } from '../extensions/session-input.js';
8
8
  import type { CoreAgentsBackend } from '../extensions/agents.js';
9
9
  import type { HostDescription, MarAgentHost } from '../host/contracts.js';
10
- import { type MarAgentReasoningEffort } from '../model/configuration.js';
10
+ import type { MarAgentReasoningEffort } from '../model/configuration.js';
11
11
  import type { ModelAdapter, ModelMessage } from '../model/contracts.js';
12
12
  import { CompactRequests } from '../runtime/compaction/requests.js';
13
13
  import { JsonlSessionStore } from '../session/store/index.js';
@@ -1,11 +1,12 @@
1
1
  import { restoreMessages } from '../runtime/context/restore.js';
2
2
  import { createNativeSteer } from './native-steer.js';
3
- import { lastConfigurationEffort, latestModelUsage, reasoningEffortBaseline } from '../runtime/context/usage.js';
3
+ import { latestModelUsage, reasoningEffortBaseline } from '../runtime/context/usage.js';
4
4
  import { splitContextualPrompt } from '../runtime/context/contextual-blocks.js';
5
- import { contextualInstructionInsertIndex, insertContextualWorldState, latestContextualWorldStateGeneration, parsePersistedContextualWorldState, persistContextualWorldState, resetContextualWorldState, updateContextualWorldState, updatePromptWorldState } from '../runtime/context/world-state.js';
5
+ import { contextualInstructionInsertIndex, latestContextualWorldStateGeneration, parsePersistedContextualWorldState, persistContextualWorldState, resetContextualWorldState, updateContextualWorldState, updatePromptWorldState } from '../runtime/context/world-state.js';
6
6
  import { eventForPersistence, publicModelUsage } from '../runtime/event-projection.js';
7
7
  import { ExecutionLoop } from '../runtime/execution.js';
8
- import { closeModelAdapters, createModelTurnSession } from './model-runtime.js';
8
+ import { closeModelAdapters, createExecutionModelResources, createModelTurnSession } from './model-runtime.js';
9
+ import { prepareSessionModelRequest, projectSessionRequestMessages } from './request-preparation.js';
9
10
  import { createSubagentBackend } from './subagent-backend.js';
10
11
  import { ExecutionToolPermissions, projectPermissionTool, resolvePermissionMode, withToolPermissions } from '../tools/permissions.js';
11
12
  import { createToolWaitInterrupt } from '../tools/wait.js';
@@ -24,7 +25,7 @@ import { createExtensionAgentsBackend } from './extension-agents.js';
24
25
  import { coreMcpCatalog } from '../extensions/mcp.js';
25
26
  import { isDeepStrictEqual } from 'node:util';
26
27
  import { MarAgentError, describeMarAgentError } from '../error.js';
27
- import { usesResponsesConfigurationUpdates } from '../model/configuration.js';
28
+ import { prepareModelConfiguration } from '../model/request-configuration.js';
28
29
  import { autoPermissionPrompt } from '../prompts/permissions.js';
29
30
  import { MAR_AGENT_PROMPT_VERSION, buildSystemPromptSections } from '../prompts/index.js';
30
31
  import { renderPromptSections } from '../extensions/prompt-composition.js';
@@ -43,12 +44,11 @@ import { ContextGcRuntime } from '../runtime/context/gc-runtime.js';
43
44
  import { AGENT_EXECUTION_POLICY } from '../runtime/execution-policy.js';
44
45
  import { loadAgentInstructions, renderAgentInstructions } from '../runtime/context/instructions.js';
45
46
  import { normalizeMessagesForModel } from '../runtime/context/normalize.js';
46
- import { latestSmartContextTokens, projectSmartCompactionMessage, requestSmartCompaction } from '../runtime/compaction/smart.js';
47
+ import { latestSmartContextTokens, requestSmartCompaction } from '../runtime/compaction/smart.js';
47
48
  import { compactSummaryFromCheckpoint, inputMetadataFromRecord } from '../session/store/index.js';
48
49
  import { SubagentSessionController } from '../subagent/session-controller.js';
49
50
  import { agentStartToolDefinitionWithModels } from '../tools/agent/agent-start.js';
50
51
  import { allowsDirectTool, allowsToolCaller, toolCallers } from '../tools/callers.js';
51
- import { projectCodeModeSearchResult, projectCodeModeTools } from '../tools/code-mode/index.js';
52
52
  import { assertMcpToolCatalog } from '../tools/mcp/catalog.js';
53
53
  import { BUILTIN_TOOL_DEFINITIONS } from '../tools/registry.js';
54
54
  import { createSessionToolScheduler } from '../tools/scheduler.js';
@@ -362,10 +362,9 @@ export function createSessionOpener(services) {
362
362
  let finalAnswer = '';
363
363
  let executionLoop;
364
364
  let executionToolSources;
365
- let selectedTurn;
366
365
  const contextGc = new ContextGcRuntime();
367
366
  let selectedAdapter;
368
- const executionScopedAdapters = new Set();
367
+ const modelResources = createExecutionModelResources(activeExecutionAdapters);
369
368
  const subagents = sessionSource.type === 'user' ? sessionRuntime.subagents : undefined;
370
369
  try {
371
370
  controller.signal.throwIfAborted();
@@ -767,28 +766,11 @@ export function createSessionOpener(services) {
767
766
  });
768
767
  selectedAdapter = sessionAdapter(input.modelId ?? executionDefaultModelId, executionModels);
769
768
  const selectedModel = executionModels.get(input.modelId ?? executionDefaultModelId);
770
- if (services.hasCustomAdapters && selectedAdapter.createTurnSession === undefined) {
771
- executionScopedAdapters.add(selectedAdapter);
772
- activeExecutionAdapters.add(selectedAdapter);
773
- }
774
- const selected = createModelTurnSession(selectedAdapter);
775
- selectedTurn = selected;
769
+ const selected = modelResources.openTurn(selectedAdapter, services.hasCustomAdapters && selectedAdapter.createTurnSession === undefined);
776
770
  let lastServerUsage = latestModelUsage(contextRecords, selectedModel.id);
777
771
  let smartContextTokens = latestSmartContextTokens(contextRecords, selectedModel.id, selectedModel.contextWindowTokens);
778
772
  const compactUserTokenLimit = Math.min(20_000, Math.floor(selectedModel.contextWindowTokens / 8));
779
773
  const reasoningEffort = input.reasoningEffort ?? selectedModel.defaultReasoningEffort;
780
- const useEffortUpdates = usesResponsesConfigurationUpdates(selectedModel);
781
- const previousReasoningEffort = useEffortUpdates
782
- ? reasoningEffortBaseline(contextRecords, selectedModel.id)
783
- : undefined;
784
- let requestReasoningEffort = useEffortUpdates
785
- ? (previousReasoningEffort ?? reasoningEffort)
786
- : undefined;
787
- let effectiveReasoningEffort = useEffortUpdates
788
- ? previousReasoningEffort === undefined
789
- ? requestReasoningEffort
790
- : (lastConfigurationEffort(messages, selectedModel.id) ?? requestReasoningEffort)
791
- : undefined;
792
774
  if (mode !== 'compact' && subagents)
793
775
  await subagents.beginParentExecution({
794
776
  executionId,
@@ -1310,25 +1292,21 @@ export function createSessionOpener(services) {
1310
1292
  diagnose: () => coreExtensions.diagnose({ code: 'MAR_AGENT_STEER_POST_COMMIT_FAILED', sessionId })
1311
1293
  });
1312
1294
  }
1313
- if (mode !== 'compact' &&
1314
- useEffortUpdates &&
1315
- effectiveReasoningEffort !== reasoningEffort) {
1316
- const update = {
1317
- role: 'provider',
1318
- content: '',
1319
- provider: 'OPENAI_RESPONSES',
1320
- providerModelId: selectedModel.id,
1321
- item: { type: 'configuration_update', reasoning: { effort: reasoningEffort } }
1322
- };
1323
- messages.push(update);
1324
- await store.append(sessionId, {
1325
- type: 'model.context',
1326
- payload: update,
1327
- executionId,
1328
- turnId
1329
- });
1330
- effectiveReasoningEffort = reasoningEffort;
1331
- }
1295
+ const modelConfiguration = prepareModelConfiguration(selectedModel, reasoningEffort, {
1296
+ baselineEffort: reasoningEffortBaseline(contextRecords, selectedModel.id),
1297
+ messages
1298
+ });
1299
+ let requestReasoningEffort = modelConfiguration.requestReasoningEffort;
1300
+ if (mode !== 'compact')
1301
+ for (const update of modelConfiguration.updates) {
1302
+ messages.push(update);
1303
+ await store.append(sessionId, {
1304
+ type: 'model.context',
1305
+ payload: update,
1306
+ executionId,
1307
+ turnId
1308
+ });
1309
+ }
1332
1310
  const runPreparedExecution = async (compactFocus = input.prompt, compactSignal = controller.signal) => {
1333
1311
  const initialSystemPrompt = mode === 'compact'
1334
1312
  ? buildExecutionSystemPrompt(executionTools, 'run')
@@ -1403,8 +1381,9 @@ export function createSessionOpener(services) {
1403
1381
  lastServerContextTokens = undefined;
1404
1382
  lastServerUsage = undefined;
1405
1383
  smartContextTokens = undefined;
1406
- requestReasoningEffort = reasoningEffort;
1407
- effectiveReasoningEffort = reasoningEffort;
1384
+ requestReasoningEffort = prepareModelConfiguration(selectedModel, reasoningEffort, {
1385
+ checkpointAdopted: true
1386
+ }).requestReasoningEffort;
1408
1387
  };
1409
1388
  const compactLeaf = async (input, signal, prepare, compactionId) => {
1410
1389
  if (messages.length < 2)
@@ -1688,37 +1667,27 @@ export function createSessionOpener(services) {
1688
1667
  executionEnvironment = { ...currentEnvironment, ...currentLocalTimeContext() };
1689
1668
  await modelContext.recordEnvironment();
1690
1669
  const { roundTools, roundBindings, toolScope, composeSystemPrompt } = captureRoundToolScope();
1691
- const codeModeEnabled = roundTools.some((tool) => tool.name === 'code_exec');
1692
1670
  const residentTools = projectTools(mcpRegistry.projectDirect(baseTools()));
1693
- const requestTools = (() => {
1694
- if (selectedModel.protocol !== 'OPENAI_RESPONSES')
1695
- return projectCodeModeTools(roundTools, residentTools);
1696
- const directNames = new Set(residentTools.map((tool) => tool.name));
1697
- // Discovery and caller policy are independent: keep nested declarations for active tools.
1698
- return projectCodeModeTools(roundTools, residentTools).filter((tool) => directNames.has(tool.name));
1699
- })();
1700
1671
  const requestContextMessages = pendingOutputContinuation === undefined
1701
1672
  ? messages
1702
1673
  : [...messages, pendingOutputContinuation];
1703
1674
  sources.bind(toolScope);
1704
1675
  const composedSystem = splitContextualPrompt(await composeSystemPrompt());
1705
1676
  const candidateWorld = updatePromptWorldState(modelContext.worldState, messages.length, composedSystem.parts);
1706
- const modelMessages = projectSessionRequestMessages(requestContextMessages, candidateWorld.entries, selectedModel.inputCapabilities.includes('IMAGE'), codeModeEnabled, permissionPolicy.mode === 'auto');
1707
- const systemPrompt = composedSystem.system;
1708
- const candidateRequest = {
1709
- system: systemPrompt,
1677
+ const candidateRequest = prepareSessionModelRequest({
1678
+ system: composedSystem.system,
1710
1679
  ...(composedSystem.systemBlocks
1711
1680
  ? { systemBlocks: composedSystem.systemBlocks }
1712
1681
  : {}),
1713
- messages: modelMessages,
1714
- tools: requestTools,
1682
+ messages: requestContextMessages,
1683
+ tools: roundTools,
1715
1684
  promptCacheKey: sessionId,
1716
1685
  reasoningEffort,
1717
1686
  ...(requestReasoningEffort === undefined ? {} : { requestReasoningEffort }),
1718
1687
  ...(modelInputImages?.length ? { images: modelInputImages } : {}),
1719
1688
  onAttemptDiagnostic: recordModelAttempt('EXECUTION')
1720
- };
1721
- preparingRequestMessages = modelMessages;
1689
+ }, selectedModel, candidateWorld.entries, residentTools, permissionPolicy.mode === 'auto');
1690
+ preparingRequestMessages = candidateRequest.messages;
1722
1691
  preparingRequestBaseLength = messages.length;
1723
1692
  let request;
1724
1693
  try {
@@ -1803,8 +1772,7 @@ export function createSessionOpener(services) {
1803
1772
  modelId: selectedModel.id,
1804
1773
  contextWindowTokens: selectedModel.contextWindowTokens,
1805
1774
  usage: latestUsage,
1806
- modelProtocol: selectedModel.protocol,
1807
- responsesConfigurationUpdates: usesResponsesConfigurationUpdates(selectedModel),
1775
+ ...modelConfiguration.contextProjection,
1808
1776
  workspace: logicalWorkspace,
1809
1777
  platform: description.platform,
1810
1778
  getActiveProcessIds: async () => {
@@ -1894,6 +1862,7 @@ export function createSessionOpener(services) {
1894
1862
  };
1895
1863
  }
1896
1864
  finally {
1865
+ // Revoke this Execution's request and input bindings, not Session warm resources.
1897
1866
  delete executionContext.requestMessages;
1898
1867
  compactRequests.close(new MarAgentError('MAR_AGENT_CANCELLED', 'Execution ended.'));
1899
1868
  if (executionContext.compactRequests === compactRequests)
@@ -1905,18 +1874,10 @@ export function createSessionOpener(services) {
1905
1874
  if (executionContext.toolSources === executionToolSources)
1906
1875
  delete executionContext.toolSources;
1907
1876
  internal.signal?.removeEventListener('abort', abortSource);
1877
+ // Compact retains its existing owner, waiting and error propagation.
1908
1878
  await compactCoordinator.close(controller.signal.reason ?? new MarAgentError('MAR_AGENT_CANCELLED', 'Execution ended.'));
1909
- await selectedTurn?.close().catch(() => undefined);
1910
- try {
1911
- await closeModelAdapters(executionScopedAdapters);
1912
- }
1913
- catch {
1914
- // Execution cleanup is best effort.
1915
- }
1916
- finally {
1917
- for (const adapter of executionScopedAdapters)
1918
- activeExecutionAdapters.delete(adapter);
1919
- }
1879
+ await modelResources.close();
1880
+ // Ending the parent Execution does not destroy Session-owned child tasks.
1920
1881
  subagents?.endParentExecution(executionId);
1921
1882
  try {
1922
1883
  await releaseSession?.();
@@ -1927,6 +1888,7 @@ export function createSessionOpener(services) {
1927
1888
  throw error;
1928
1889
  }
1929
1890
  finally {
1891
+ // Writer release cannot skip owner-safe deactivation; the event stream closes last.
1930
1892
  if (sessionRuntime.execution === executionContext)
1931
1893
  delete sessionRuntime.execution;
1932
1894
  active.delete(`${sessionId}:${executionId}`);
@@ -2262,14 +2224,6 @@ function modelAttemptFailureDiagnostic(diagnostic, summary) {
2262
2224
  message: `${prefix}${[...diagnostic.message].slice(0, availableCharacters).join('')}`
2263
2225
  };
2264
2226
  }
2265
- /** Shared, side-effect-free projection for the real request and current Session request view. */
2266
- function projectSessionRequestMessages(messages, entries, supportsImages, codeMode, autoPermission = false) {
2267
- return normalizeMessagesForModel(insertContextualWorldState(messages, entries), {
2268
- supportsImages
2269
- }).map((message) => projectCodeModeSearchResult(autoPermission && message.toolSearchTools
2270
- ? { ...message, toolSearchTools: message.toolSearchTools.map(projectPermissionTool) }
2271
- : projectSmartCompactionMessage(message), codeMode));
2272
- }
2273
2227
  function projectAppendedModelMessage(input) {
2274
2228
  if (input.visibility === 'transcript')
2275
2229
  return undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myagentroam/agent",
3
- "version": "0.11.6",
3
+ "version": "0.11.8",
4
4
  "description": "Embeddable MAR coding agent SDK and CLI.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",