@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.
- package/dist/prompts/compact.js +4 -2
- package/dist/prompts/core.d.ts +1 -1
- package/dist/prompts/core.js +3 -3
- package/dist/prompts/execution-budget.d.ts +2 -5
- package/dist/prompts/execution-budget.js +9 -8
- package/dist/prompts/index.d.ts +1 -6
- package/dist/prompts/index.js +3 -8
- package/dist/prompts/modes.d.ts +0 -1
- package/dist/prompts/modes.js +3 -9
- package/dist/prompts/subagent.d.ts +0 -13
- package/dist/prompts/subagent.js +0 -27
- package/dist/runtime/compact.js +1 -1
- package/dist/runtime/environment-context.d.ts +1 -1
- package/dist/runtime/environment-context.js +2 -2
- package/dist/sdk/agent.js +31 -28
- package/dist/tools/agent-start.d.ts +5 -0
- package/dist/tools/agent-start.js +19 -0
- package/package.json +1 -1
package/dist/prompts/compact.js
CHANGED
|
@@ -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。
|
package/dist/prompts/core.d.ts
CHANGED
|
@@ -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;
|
package/dist/prompts/core.js
CHANGED
|
@@ -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 { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[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
|
|
3
|
-
|
|
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
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
}
|
package/dist/prompts/index.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { ExecutionMode } from '../sdk/types.js';
|
|
2
|
-
|
|
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;
|
package/dist/prompts/index.js
CHANGED
|
@@ -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 {
|
|
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.
|
|
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)
|
package/dist/prompts/modes.d.ts
CHANGED
package/dist/prompts/modes.js
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
export function modePrompt(mode, input) {
|
|
2
2
|
if (mode !== 'plan')
|
|
3
3
|
return '';
|
|
4
|
-
const investigationGuidance =
|
|
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.
|
|
10
|
-
|
|
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.";
|
package/dist/prompts/subagent.js
CHANGED
|
@@ -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.';
|
package/dist/runtime/compact.js
CHANGED
|
@@ -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
|
|
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)
|