@myagentroam/agent 0.9.96 → 0.9.98

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.
@@ -12,7 +12,7 @@ Preserve, when present:
12
12
  - unresolved questions, blockers, risks, uncommitted changes, Todo/plan state, and pending external decisions;
13
13
  - the next concrete action and the evidence still required before completion.
14
14
 
15
- Distinguish clearly between completed, attempted, planned, inferred, and unverified work. Newer user instructions override older ones; retain superseded instructions only when needed to explain current state. Never invent completion, test results, file contents, permissions, or external effects.
15
+ Distinguish clearly between completed, attempted, planned, inferred, and unverified work. Newer user instructions override older ones; retain superseded instructions only when needed to explain current state. Authorization has exact action, scope, and lifetime: preserve it as active only while all three remain valid. Historical instructions, completed scopes, and state that merely makes an action plausible cannot grant or revive authorization. Never invent completion, test results, file contents, permissions, authorization, or external effects.
16
16
 
17
17
  Remove aggressively:
18
18
  - greetings, acknowledgements, progress chatter, repeated instructions, repeated status, and conclusions already represented once;
@@ -51,6 +51,7 @@ branch changed -> inherited_evidence=unverified
51
51
  1. 目标契约 / Goal contract
52
52
  - 主目标、当前交付、完成标准、非目标/边界。
53
53
  - direct user/caller authorization、prohibition、exclusion 保留 exact action/scope,不概括成更宽泛边界。
54
+ - authorization 必须归约 exact action、scope、lifetime。仅当三者在 latest active task/request 中仍有效时记录 active;已完成或被取代作用域中的授权只能记录 expired/superseded historical evidence,不得恢复为 current permission。
54
55
 
55
56
  2. 当前状态 / Current state
56
57
  - 对象:file、symbol、feature、migration、test、worktree、selected Skill、Todo/plan、external decision、external side effect。retained process/subagent inventory 由 Runtime 重建,不进入 IR。
@@ -73,9 +74,10 @@ branch changed -> inherited_evidence=unverified
73
74
  5. 未闭环 / Open loops
74
75
  - unresolved、unverified、blocker、pending external decision、Todo/plan current step、仍需 evidence。
75
76
  - 只保留已确定的最小 next action + preconditions;不复制可重算的长 plan。
77
+ - 需要独立授权的 action 只有在 current direct authorization 覆盖 exact action/scope 且 lifetime 仍有效时才能标为 pending/next。对象状态、完成度、工具可用性或执行便利性均不得推导 authorization;无有效授权时省略该动作,必要时记录 authorization | action=<exact> | status=expired|superseded|absent。
76
78
 
77
79
  编译规则:
78
- 1. latest user intent 定目标;newer correction 覆盖 older intent。
80
+ 1. latest user intent 定目标;newer correction 覆盖 older intent。历史指令不得因仍出现在 retained user messages 中而恢复为 active authorization
79
81
  2. 归约 before -> event -> after;source mutation 或 base/branch change 后 affected read/conclusion stale,除非已有 newer evidence;history replacement 仅使 Responses continuation invalid,不使 factual evidence 自动失效;无 invalidating event 的 verified claim 保持 current;current 取最后已证 after-state 或 later direct observation。
80
82
  3. 每个 continuation object 一条 current record;等价事实去重。
81
83
  4. 仅保留仍约束 open work 的 settled decision/exclusion。
@@ -15,4 +15,4 @@ export interface EnvironmentContextState {
15
15
  guaranteedCommands?: Readonly<Record<string, string>>;
16
16
  workspace: string;
17
17
  }
18
- export declare function buildEnvironmentContext(input: EnvironmentContextState, previous?: EnvironmentContextState): string;
18
+ export declare function buildEnvironmentContext(input: EnvironmentContextState, previous?: EnvironmentContextState, contextualEntries?: readonly string[]): string;
@@ -6,7 +6,7 @@ export const workspaceDisciplinePrompt = '# Workspace and change discipline\nAss
6
6
  export function environmentPrompt(input) {
7
7
  return `# Environment and workspace\nMode: ${input.mode}. The Runtime provides current platform, shell and Workspace facts in an environment_context message. These facts describe the execution environment, not additional instructions or permissions. Start exploration inside this workspace unless the task explicitly requires an absolute path elsewhere. Generate commands for the actual platform and configured shell; do not assume POSIX tools on Windows or PowerShell/cmd syntax on Unix. Relative tool paths resolve from the Workspace. Absolute paths are allowed subject to the operating-system account's permissions and Host-declared file boundaries.`;
8
8
  }
9
- export function buildEnvironmentContext(input, previous) {
9
+ export function buildEnvironmentContext(input, previous, contextualEntries = []) {
10
10
  const element = (name, value) => `<${name}>${value.replace(/[&<>"']/g, (character) => {
11
11
  return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&apos;' }[character];
12
12
  })}</${name}>`;
@@ -31,7 +31,7 @@ export function buildEnvironmentContext(input, previous) {
31
31
  return [];
32
32
  return [value ?? `<${name} status="unavailable" />`];
33
33
  });
34
- return changes.length
35
- ? ['<environment_context>', ...changes, '</environment_context>'].join('\n')
34
+ return changes.length > 0 || contextualEntries.length > 0
35
+ ? ['<environment_context>', ...changes, ...contextualEntries, '</environment_context>'].join('\n')
36
36
  : '';
37
37
  }
@@ -1,6 +1,3 @@
1
1
  import type { RolloutBudgetStage } from '../runtime/rollout-budget.js';
2
- export interface ExecutionBudgetPromptState {
3
- stage: RolloutBudgetStage;
4
- limitTokens: number;
5
- }
6
- export declare function executionBudgetPrompt(input: ExecutionBudgetPromptState): string;
2
+ export type ExecutionBudgetEnvironmentStage = Exclude<RolloutBudgetStage, 'normal'> | 'inactive';
3
+ export declare function executionBudgetEnvironmentEntry(stage: ExecutionBudgetEnvironmentStage): string;
@@ -1,10 +1,11 @@
1
- export function executionBudgetPrompt(input) {
1
+ export function executionBudgetEnvironmentEntry(stage) {
2
+ if (stage === 'inactive')
3
+ return '<execution_guidance status="inactive" />';
2
4
  const privateInstruction = 'This is internal runtime guidance. Never mention the budget, thresholds, remaining amount, or budget stage in user-visible progress or the final answer.';
3
- if (input.stage === 'exhausted')
4
- return `# Execution budget\n${privateInstruction}\n\nThe shared rollout budget is exhausted. Do not start or continue investigation, optional work, new tool exploration, or new subagents. Return a concise final answer now using the current verified staged result. Clearly distinguish completed work from anything still incomplete, without mentioning this budget.`;
5
- if (input.stage === 'finalize')
6
- return `# Execution budget\n${privateInstruction}\n\nEnter finalization now. Do not start new investigation or new subagents. Complete only the current atomic change, the minimum necessary verification, and the final answer as soon as possible.`;
7
- if (input.stage === 'conserve')
8
- return `# Execution budget\n${privateInstruction}\n\nStop expanding scope and stop optional work. Prefer completing the current objective with the evidence already gathered, and avoid new investigation unless it is strictly required for correctness.`;
9
- return `# Execution budget\n${privateInstruction}\n\nThis main Execution and the subagents it creates share an internal weighted token budget of ${input.limitTokens}. Work normally, but keep scope disciplined and converge once the requested outcome is verified.`;
5
+ const guidance = stage === 'exhausted'
6
+ ? 'The shared rollout budget is exhausted. Do not start or continue investigation, optional work, new tool exploration, or new subagents. Return a concise final answer now using the current verified staged result. Clearly distinguish completed work from anything still incomplete, without mentioning this budget.'
7
+ : stage === 'finalize'
8
+ ? 'Enter finalization now. Do not start new investigation or new subagents. Complete only the current atomic change, the minimum necessary verification, and the final answer as soon as possible.'
9
+ : 'Stop expanding scope and stop optional work. Prefer completing the current objective with the evidence already gathered, and avoid new investigation unless it is strictly required for correctness.';
10
+ return `<execution_guidance stage="${stage}">\n${privateInstruction}\n\n${guidance}\n</execution_guidance>`;
10
11
  }
@@ -1,7 +1,5 @@
1
1
  import type { ExecutionMode } from '../sdk/types.js';
2
- import { type ExecutionBudgetPromptState } from './execution-budget.js';
3
- import { type CurrentAgentModel, type SubagentModelOption } from './subagent.js';
4
- export declare const MAR_AGENT_PROMPT_VERSION = "1.52";
2
+ export declare const MAR_AGENT_PROMPT_VERSION = "1.55";
5
3
  export declare function buildSystemPrompt(input: {
6
4
  mode: ExecutionMode;
7
5
  platform: string;
@@ -13,9 +11,6 @@ export declare function buildSystemPrompt(input: {
13
11
  guaranteedCommands?: Readonly<Record<string, string>>;
14
12
  workspace: string;
15
13
  tools: readonly string[];
16
- currentAgentModel?: CurrentAgentModel;
17
- subagentModels?: readonly SubagentModelOption[];
18
- executionBudget?: ExecutionBudgetPromptState;
19
14
  highDensityCompaction?: boolean;
20
15
  extension?: string | undefined;
21
16
  }): string;
@@ -1,11 +1,10 @@
1
1
  import { compactionPrompt, highDensityCompactionPrompt } from './compact.js';
2
2
  import { environmentPrompt, identityPrompt, instructionPriorityPrompt, workspaceDisciplinePrompt } from './core.js';
3
- import { executionBudgetPrompt } from './execution-budget.js';
4
3
  import { modePrompt } from './modes.js';
5
4
  import { outputStylePrompt } from './output.js';
6
- import { subagentModelOptionsPrompt, subagentPrompt, currentAgentModelPrompt } from './subagent.js';
5
+ import { subagentPrompt } from './subagent.js';
7
6
  import { interactionPrompt, longRunningPrompt, safetyPrompt, toolUsagePrompt, workflowPrompt } from './workflow.js';
8
- export const MAR_AGENT_PROMPT_VERSION = '1.52';
7
+ export const MAR_AGENT_PROMPT_VERSION = '1.55';
9
8
  export function buildSystemPrompt(input) {
10
9
  const toolNames = new Set(input.tools);
11
10
  const hasLongRunningCapability = [
@@ -27,10 +26,8 @@ export function buildSystemPrompt(input) {
27
26
  environmentPrompt(input),
28
27
  input.tools.length > 0 ? toolUsagePrompt(input.tools) : '',
29
28
  hasLongRunningCapability ? longRunningPrompt(input.tools) : '',
30
- input.executionBudget ? executionBudgetPrompt(input.executionBudget) : '',
31
29
  modePrompt(input.mode, {
32
- questionAvailable: toolNames.has('question'),
33
- forceFinalize: input.executionBudget?.stage === 'exhausted'
30
+ questionAvailable: toolNames.has('question')
34
31
  }),
35
32
  input.mode === 'compact'
36
33
  ? input.highDensityCompaction
@@ -38,8 +35,6 @@ export function buildSystemPrompt(input) {
38
35
  : compactionPrompt()
39
36
  : '',
40
37
  toolNames.has('agent_start') ? subagentPrompt : '',
41
- toolNames.has('agent_start') ? currentAgentModelPrompt(input.currentAgentModel) : '',
42
- toolNames.has('agent_start') ? subagentModelOptionsPrompt(input.subagentModels ?? []) : '',
43
38
  input.extension ? `# Caller, project, and selected Skill instructions\n${input.extension}` : ''
44
39
  ]
45
40
  .filter(Boolean)
@@ -1,5 +1,4 @@
1
1
  import type { ExecutionMode } from '../sdk/types.js';
2
2
  export declare function modePrompt(mode: ExecutionMode, input: {
3
3
  questionAvailable: boolean;
4
- forceFinalize: boolean;
5
4
  }): string;
@@ -1,17 +1,11 @@
1
1
  export function modePrompt(mode, input) {
2
2
  if (mode !== 'plan')
3
3
  return '';
4
- const investigationGuidance = input.forceFinalize
5
- ? 'Use only evidence already gathered; do not start or continue Plan exploration.'
6
- : 'Resolve discoverable facts through targeted read-only investigation. Ask about user-owned preferences and tradeoffs early when they cannot be inferred from the request, conversation, or workspace evidence.';
4
+ const investigationGuidance = 'Resolve discoverable facts through targeted read-only investigation. Ask about user-owned preferences and tradeoffs early when they cannot be inferred from the request, conversation, or workspace evidence. If current environment guidance requires finalization, stop further exploration and use only evidence already gathered.';
7
5
  const decisionGuidance = input.questionAvailable
8
6
  ? 'Use question for unresolved choices that materially change the result; do not finalize the plan while such choices remain. Do not invent support for multiple outcomes or silently choose a default to avoid asking.'
9
- : input.forceFinalize
10
- ? 'User input is unavailable in this exhausted round. Return the current verified staged result now; state the unresolved decision and its impact instead of guessing.'
11
- : 'Ask a concise plain-text question for unresolved user-owned choices that materially change the result instead of finalizing an ambiguous plan. Do not invent support for multiple outcomes or silently choose a default.';
12
- const finalGuidance = input.forceFinalize
13
- ? 'Return only the concise staged plan now, distinguishing verified conclusions from incomplete work and unresolved decisions. Do not ask whether to proceed or claim unresolved work is complete.'
14
- : 'Once the plan is decision-complete, return only a concise, actionable plan. Break the work into meaningful, logically ordered deliverables that are easy to verify. Do not pad the plan with filler or obvious steps. Include the implementation and verification detail needed to execute it, without drafting the implementation itself. Do not ask whether to proceed or claim planned work is completed.';
7
+ : 'Ask a concise plain-text question for unresolved user-owned choices that materially change the result instead of finalizing an ambiguous plan. When current environment guidance requires finalization and user input is unavailable, state the unresolved decision and its impact instead of guessing. Do not invent support for multiple outcomes or silently choose a default.';
8
+ const finalGuidance = 'Once the plan is decision-complete, return only a concise, actionable plan. Break the work into meaningful, logically ordered deliverables that are easy to verify. Do not pad the plan with filler or obvious steps. Include the implementation and verification detail needed to execute it, without drafting the implementation itself. When current environment guidance requires finalization, return the concise verified staged plan and distinguish incomplete work or unresolved decisions. Do not ask whether to proceed or claim unresolved work is complete.';
15
9
  return `# Plan mode
16
10
  Use tools only for read-only investigation that reduces uncertainty and improves the plan. Do not create, modify, delete, rename, or move files, and do not run commands intended to mutate repository-tracked state or implement the requested work. This is behavioral guidance, not a security boundary; the normal tools and Host policies remain available.
17
11
 
@@ -1,15 +1,2 @@
1
1
  export declare const subagentPrompt = "# Subagents\nUse your own direct tools by default. Delegate only when a bounded task can proceed independently and parallelism has real value; do not delegate ordinary local search, a known-file read, a single verification command, a small edit, or sequential debugging. Give each child a self-contained objective, relevant paths and constraints, expected evidence, and a clear read/write boundary. Subagents cannot recurse and share the real filesystem; do not assign conflicting writes or assume isolation. Track background agent IDs, wait or cancel them, inspect their actual workspace effects, and verify every claim before incorporating it. Continue meaningful non-overlapping work after starting a background child. Wait for completion only when the next critical-path action is blocked on the final result, and then prefer one long wait measured in minutes rather than repeated short waits. Wait for a public message only when a fresh progress update would change the next decision; do not use message waits as heartbeat checks or request progress merely to confirm that a child is still running. The parent retains responsibility for the final result.";
2
- export interface SubagentModelOption {
3
- readonly id: string;
4
- readonly name: string;
5
- readonly default: boolean;
6
- readonly reasoningEfforts: readonly string[];
7
- }
8
- export interface CurrentAgentModel {
9
- readonly id: string;
10
- readonly name: string;
11
- readonly reasoningEffort: string;
12
- }
13
- export declare function currentAgentModelPrompt(model: CurrentAgentModel | undefined): string;
14
- export declare function subagentModelOptionsPrompt(options: readonly SubagentModelOption[]): string;
15
2
  export declare const childSubagentInstruction = "You are a non-recursive subagent. Work only on the delegated objective and within its stated read/write scope. Do not broaden the parent task, ask the user, start another subagent, commit, or claim parent-level completion. Inspect relevant evidence, make only authorized changes, run proportional verification, and return a concise factual handoff containing findings, exact files changed, commands/tests actually run, failures or uncertainty, and anything the parent must verify.";
@@ -1,29 +1,2 @@
1
1
  export const subagentPrompt = '# Subagents\nUse your own direct tools by default. Delegate only when a bounded task can proceed independently and parallelism has real value; do not delegate ordinary local search, a known-file read, a single verification command, a small edit, or sequential debugging. Give each child a self-contained objective, relevant paths and constraints, expected evidence, and a clear read/write boundary. Subagents cannot recurse and share the real filesystem; do not assign conflicting writes or assume isolation. Track background agent IDs, wait or cancel them, inspect their actual workspace effects, and verify every claim before incorporating it. Continue meaningful non-overlapping work after starting a background child. Wait for completion only when the next critical-path action is blocked on the final result, and then prefer one long wait measured in minutes rather than repeated short waits. Wait for a public message only when a fresh progress update would change the next decision; do not use message waits as heartbeat checks or request progress merely to confirm that a child is still running. The parent retains responsibility for the final result.';
2
- export function currentAgentModelPrompt(model) {
3
- if (!model)
4
- return '';
5
- return [
6
- '# Current Agent Model',
7
- `The current agent is running as ${model.id} (${promptData(model.name)}) with reasoning effort: ${model.reasoningEffort}.`
8
- ].join('\n');
9
- }
10
- export function subagentModelOptionsPrompt(options) {
11
- if (options.length === 0 || (options.length === 1 && options[0]?.reasoningEfforts.length === 0))
12
- return '';
13
- const lines = options.map((option) => {
14
- const defaultLabel = option.default ? ', default' : '';
15
- const effortLabel = option.reasoningEfforts.length === 0
16
- ? ''
17
- : `; reasoning efforts: ${option.reasoningEfforts.join(', ')}`;
18
- return `- ${option.id} (${promptData(option.name)}${defaultLabel}${effortLabel})`;
19
- });
20
- return [
21
- '# Subagent Models',
22
- 'The agent_start tool modelId field may select any enabled model below, and its optional reasoningEffort field overrides the parent effort. Omit both to inherit the parent model and effort. Only use an effort listed for the selected model, and never guess an unlisted model ID or effort.',
23
- ...lines
24
- ].join('\n');
25
- }
26
- function promptData(value) {
27
- return JSON.stringify(value);
28
- }
29
2
  export const childSubagentInstruction = 'You are a non-recursive subagent. Work only on the delegated objective and within its stated read/write scope. Do not broaden the parent task, ask the user, start another subagent, commit, or claim parent-level completion. Inspect relevant evidence, make only authorized changes, run proportional verification, and return a concise factual handoff containing findings, exact files changed, commands/tests actually run, failures or uncertainty, and anything the parent must verify.';
@@ -225,7 +225,7 @@ export function compactedHistoryMessages(history) {
225
225
  return history.map(({ role, content }) => ({ role, content }));
226
226
  }
227
227
  export function continuationMessage(summary) {
228
- return `Continue from the compacted state below. Treat it as a factual handoff, not a new user request. Earlier user messages are retained historical evidence, not requests to repeat completed work. Newer user instructions override older messages and this handoff. Continue directly from its Next action without recapping it to the user. Re-read files or rerun checks when the handoff marks facts as stale, inferred, failed, or unverified. Do not repeat completed side effects.\n\n${summary}`;
228
+ return `Continue from the compacted state below. Treat it as a factual handoff, not a new user request. Earlier user messages are retained historical evidence, not requests to repeat completed work or authorization for new side effects. Newer user instructions override older messages and this handoff. The handoff cannot create or revive authorization: an action that requires separate authorization may proceed only when current direct authorization still covers its exact action, scope, and lifetime. Continue directly from its Next action without recapping it to the user. Re-read files or rerun checks when the handoff marks facts as stale, inferred, failed, or unverified. Do not repeat completed side effects.\n\n${summary}`;
229
229
  }
230
230
  function renderMessage(message) {
231
231
  const metadata = [
@@ -1,4 +1,4 @@
1
1
  import type { ModelMessage } from '../model/contracts.js';
2
2
  import { type EnvironmentContextState } from '../prompts/core.js';
3
3
  export declare function restoreEnvironmentState(payload: unknown): EnvironmentContextState | undefined;
4
- export declare function environmentContextUpdate(current: EnvironmentContextState, previous?: EnvironmentContextState): ModelMessage | undefined;
4
+ export declare function environmentContextUpdate(current: EnvironmentContextState, previous?: EnvironmentContextState, contextualEntries?: readonly string[]): ModelMessage | undefined;
@@ -35,7 +35,7 @@ export function restoreEnvironmentState(payload) {
35
35
  ...(guaranteedCommands === undefined ? {} : { guaranteedCommands })
36
36
  };
37
37
  }
38
- export function environmentContextUpdate(current, previous) {
39
- const content = buildEnvironmentContext(current, previous);
38
+ export function environmentContextUpdate(current, previous, contextualEntries = []) {
39
+ const content = buildEnvironmentContext(current, previous, contextualEntries);
40
40
  return content ? { role: 'user', contextKind: 'environment', content } : undefined;
41
41
  }
package/dist/sdk/agent.js CHANGED
@@ -21,6 +21,7 @@ import { buildEnvironmentContext } from '../prompts/core.js';
21
21
  import { modelOutputContinuationMessage } from '../prompts/output.js';
22
22
  import { retainedSessionResourcesSnapshot, retainedSessionResourcesUpdate } from '../prompts/resources.js';
23
23
  import { environmentContextUpdate, restoreEnvironmentState } from '../runtime/environment-context.js';
24
+ import { executionBudgetEnvironmentEntry } from '../prompts/execution-budget.js';
24
25
  import { childSubagentInstruction } from '../prompts/subagent.js';
25
26
  import { sessionTitlePrompt } from '../prompts/title.js';
26
27
  import { loadAgentInstructions, renderAgentInstructions } from '../runtime/instructions.js';
@@ -28,6 +29,7 @@ import { normalizeMessagesForModel } from '../runtime/normalize.js';
28
29
  import { compactSummaryFromCheckpoint, replacementHistoryFromCheckpoint, JsonlSessionStore } from '../session/jsonl-store.js';
29
30
  import { TodoStore } from '../tools/todo.js';
30
31
  import { BUILTIN_TOOL_DEFINITIONS } from '../tools/registry.js';
32
+ import { agentStartToolDefinitionWithModels } from '../tools/agent-start.js';
31
33
  import { executeRegisteredTool } from '../tools/runtime.js';
32
34
  import { scheduleToolCallBatch } from '../tools/scheduler.js';
33
35
  import { withCodeModeResultTypes } from '../tools/code-mode.js';
@@ -278,6 +280,20 @@ export async function createMarAgent(options) {
278
280
  includeImages: mode !== 'compact'
279
281
  });
280
282
  const messages = restored.messages;
283
+ let projectedExecutionBudgetStage;
284
+ const appendExecutionBudgetEnvironment = () => {
285
+ const currentStage = rolloutBudget?.active ? rolloutBudget.stage : 'inactive';
286
+ if (currentStage === projectedExecutionBudgetStage)
287
+ return;
288
+ const previousStage = projectedExecutionBudgetStage;
289
+ projectedExecutionBudgetStage = currentStage;
290
+ if ((previousStage === undefined &&
291
+ (currentStage === 'normal' || currentStage === 'inactive')) ||
292
+ (currentStage === 'inactive' && previousStage === 'normal'))
293
+ return;
294
+ const entry = executionBudgetEnvironmentEntry(currentStage === 'normal' ? 'inactive' : currentStage);
295
+ messages.push(environmentContextUpdate(currentEnvironment, currentEnvironment, [entry]));
296
+ };
281
297
  const appendMailboxMessages = async () => {
282
298
  let appended = false;
283
299
  while (mailbox.length > 0) {
@@ -440,7 +456,14 @@ export async function createMarAgent(options) {
440
456
  : { claimExecutionScope: true })
441
457
  })) ?? [];
442
458
  const selectedModelForTools = executionModels.get(input.modelId ?? executionDefaultModelId);
443
- const availableTools = [...BUILTIN_TOOL_DEFINITIONS, ...mcpTools].filter((tool) => {
459
+ const builtinTools = BUILTIN_TOOL_DEFINITIONS.map((tool) => tool.name === 'agent_start'
460
+ ? agentStartToolDefinitionWithModels([...executionModels.values()].map((configuration) => ({
461
+ id: configuration.id,
462
+ name: configuration.name,
463
+ reasoningEfforts: configuration.reasoningEfforts
464
+ })))
465
+ : tool);
466
+ const availableTools = [...builtinTools, ...mcpTools].filter((tool) => {
444
467
  if (sessionSource.type === 'subagent' && tool.agentScope === 'ROOT_ONLY')
445
468
  return false;
446
469
  if (sessionSource.type === 'subagent' &&
@@ -518,32 +541,7 @@ export async function createMarAgent(options) {
518
541
  : {}),
519
542
  workspace: logicalWorkspace,
520
543
  tools: availableTools.map((tool) => tool.name),
521
- ...(sessionSource.type === 'user'
522
- ? {
523
- currentAgentModel: {
524
- id: selectedModel.id,
525
- name: selectedModel.name,
526
- reasoningEffort
527
- }
528
- }
529
- : {}),
530
- subagentModels: sessionSource.type === 'user'
531
- ? [...executionModels.values()].map((configuration) => ({
532
- id: configuration.id,
533
- name: configuration.name,
534
- default: configuration.id === executionDefaultModelId,
535
- reasoningEfforts: configuration.reasoningEfforts
536
- }))
537
- : [],
538
544
  highDensityCompaction: selectedModel.highDensityCompaction,
539
- ...(rolloutBudget?.active
540
- ? {
541
- executionBudget: {
542
- stage: rolloutBudget.stage,
543
- limitTokens: rolloutBudget.limitTokens
544
- }
545
- }
546
- : {}),
547
545
  extension: [
548
546
  options.systemInstruction,
549
547
  instructionContext?.skillCatalog,
@@ -610,7 +608,7 @@ export async function createMarAgent(options) {
610
608
  const current = messages.at(-1);
611
609
  if (!current || messages.length < 2)
612
610
  return false;
613
- const retainCurrent = current.role === 'user';
611
+ const retainCurrent = current.role === 'user' && current.contextKind !== 'environment';
614
612
  let compactSummary = '';
615
613
  const compactSystemPrompt = buildExecutionSystemPrompt(executionTools, 'run');
616
614
  const compactHistory = retainCurrent ? messages.slice(0, -1) : messages;
@@ -701,6 +699,7 @@ export async function createMarAgent(options) {
701
699
  });
702
700
  contextGc.reset();
703
701
  messages.splice(0, messages.length, environmentContextUpdate(currentEnvironment), ...compactedHistoryMessages(replacementHistory));
702
+ projectedExecutionBudgetStage = undefined;
704
703
  compactionUserMessages = replacementHistory
705
704
  .filter((message) => message.kind === 'user_input')
706
705
  .map((message) => message.content);
@@ -735,6 +734,7 @@ export async function createMarAgent(options) {
735
734
  const modelRetryState = { attempts: 0 };
736
735
  while (true) {
737
736
  await appendMailboxMessages();
737
+ appendExecutionBudgetEnvironment();
738
738
  let stop;
739
739
  let sawTool = false;
740
740
  let latestUsage;
@@ -742,6 +742,7 @@ export async function createMarAgent(options) {
742
742
  const pendingTools = [];
743
743
  let incompleteToolCall = false;
744
744
  await ensureContextBudget();
745
+ appendExecutionBudgetEnvironment();
745
746
  const toolsAllowed = mode !== 'compact' && (!rolloutBudget?.active || rolloutBudget.stage !== 'exhausted');
746
747
  const roundTools = mode === 'compact' ? executionTools : toolsAllowed ? executionTools : [];
747
748
  const systemPrompt = mode === 'compact'
@@ -1158,6 +1159,7 @@ export async function createMarAgent(options) {
1158
1159
  projection: committed.projection
1159
1160
  });
1160
1161
  messages.splice(0, messages.length, ...refreshed.messages);
1162
+ projectedExecutionBudgetStage = undefined;
1161
1163
  compactionUserMessages = [...refreshed.userMessages];
1162
1164
  agentInstructionInsertIndex =
1163
1165
  refreshed.currentTurnUserIndex ?? Math.max(0, messages.length - 1);
@@ -1791,7 +1793,8 @@ function appendOnlyUsageDelta(usage, historyMessages) {
1791
1793
  const toolCallIds = new Set(usage.historyMessages
1792
1794
  .filter((message) => message.role === 'tool_call')
1793
1795
  .map((message) => message.callId));
1794
- return appended.every((message) => message.role === 'tool' && toolCallIds.has(message.callId))
1796
+ return appended.every((message) => (message.role === 'tool' && toolCallIds.has(message.callId)) ||
1797
+ (message.role === 'user' && message.contextKind === 'environment'))
1795
1798
  ? appended
1796
1799
  : undefined;
1797
1800
  }
@@ -1,6 +1,11 @@
1
1
  import type { ClientToolDefinition } from '../model/contracts.js';
2
2
  import type { ToolRuntimeContext } from './runtime-context.js';
3
3
  export declare const agentStartToolDefinition: ClientToolDefinition;
4
+ export declare function agentStartToolDefinitionWithModels(models: readonly {
5
+ readonly id: string;
6
+ readonly name: string;
7
+ readonly reasoningEfforts: readonly string[];
8
+ }[]): ClientToolDefinition;
4
9
  export declare function executeAgentStart(arguments_: unknown, context: ToolRuntimeContext): Promise<{
5
10
  content: string;
6
11
  data: import("../subagent/scheduler.js").SubagentTaskSnapshot;
@@ -27,6 +27,25 @@ export const agentStartToolDefinition = {
27
27
  additionalProperties: false
28
28
  }
29
29
  };
30
+ export function agentStartToolDefinitionWithModels(models) {
31
+ if (models.length === 0)
32
+ return agentStartToolDefinition;
33
+ const modelLines = models.map((model) => {
34
+ const efforts = model.reasoningEfforts.length === 0
35
+ ? ''
36
+ : `; reasoning efforts: ${model.reasoningEfforts.join(', ')}`;
37
+ return `- ${JSON.stringify(model.id)} (${JSON.stringify(model.name)}${efforts})`;
38
+ });
39
+ return {
40
+ ...agentStartToolDefinition,
41
+ description: [
42
+ agentStartToolDefinition.description,
43
+ 'The optional modelId may select an enabled model below. Omit modelId to use the current agent model. Only use a listed reasoning effort for the selected model.',
44
+ 'Enabled subagent models:',
45
+ ...modelLines
46
+ ].join('\n')
47
+ };
48
+ }
30
49
  export async function executeAgentStart(arguments_, context) {
31
50
  const value = parseAgentStartInput(arguments_);
32
51
  if (!context.subagents)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myagentroam/agent",
3
- "version": "0.9.96",
3
+ "version": "0.9.98",
4
4
  "description": "Embeddable MAR coding agent SDK and CLI.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",