@myagentroam/agent 0.9.125 → 0.9.127

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.
@@ -14,5 +14,7 @@ export interface EnvironmentContextState {
14
14
  };
15
15
  guaranteedCommands?: Readonly<Record<string, string>>;
16
16
  workspace: string;
17
+ currentDate?: string;
18
+ timezone?: string;
17
19
  }
18
20
  export declare function buildEnvironmentContext(input: EnvironmentContextState, previous?: EnvironmentContextState, contextualEntries?: readonly string[]): string;
@@ -18,6 +18,8 @@ export function buildEnvironmentContext(input, previous, contextualEntries = [])
18
18
  cwd: element('cwd', state.workspace),
19
19
  shell: state.shell ? element('shell', state.shell.name) : undefined,
20
20
  shell_path: state.shell ? element('shell_path', state.shell.path) : undefined,
21
+ current_date: state.currentDate ? element('current_date', state.currentDate) : undefined,
22
+ timezone: state.timezone ? element('timezone', state.timezone) : undefined,
21
23
  available_commands: commands.length
22
24
  ? `<available_commands>${commands
23
25
  .map(([name, version]) => `<available_command>${element('name', name)}${element('version', version)}</available_command>`)
@@ -2,3 +2,4 @@ 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
4
  export declare function environmentContextUpdate(current: EnvironmentContextState, previous?: EnvironmentContextState, contextualEntries?: readonly string[]): ModelMessage | undefined;
5
+ export declare function currentLocalTimeContext(instant?: Date, timezone?: string): Pick<EnvironmentContextState, 'currentDate' | 'timezone'>;
@@ -5,6 +5,11 @@ const environmentStateSchema = z
5
5
  platform: z.string().min(1).max(64),
6
6
  architecture: z.string().min(1).max(64).optional(),
7
7
  workspace: z.string().max(32768),
8
+ currentDate: z
9
+ .string()
10
+ .regex(/^\d{4}-\d{2}-\d{2}$/u)
11
+ .optional(),
12
+ timezone: z.string().min(1).max(128).optional(),
8
13
  shell: z
9
14
  .object({
10
15
  name: z.string().min(1).max(128),
@@ -27,15 +32,38 @@ export function restoreEnvironmentState(payload) {
27
32
  const parsed = environmentRecordSchema.safeParse(payload);
28
33
  if (!parsed.success)
29
34
  return undefined;
30
- const { architecture, shell, guaranteedCommands, ...required } = parsed.data.state;
35
+ const { architecture, shell, guaranteedCommands, currentDate, timezone, ...required } = parsed.data.state;
31
36
  return {
32
37
  ...required,
33
38
  ...(architecture === undefined ? {} : { architecture }),
34
39
  ...(shell === undefined ? {} : { shell }),
35
- ...(guaranteedCommands === undefined ? {} : { guaranteedCommands })
40
+ ...(guaranteedCommands === undefined ? {} : { guaranteedCommands }),
41
+ ...(currentDate === undefined ? {} : { currentDate }),
42
+ ...(timezone === undefined ? {} : { timezone })
36
43
  };
37
44
  }
38
45
  export function environmentContextUpdate(current, previous, contextualEntries = []) {
39
46
  const content = buildEnvironmentContext(current, previous, contextualEntries);
40
47
  return content ? { role: 'user', contextKind: 'environment', content } : undefined;
41
48
  }
49
+ export function currentLocalTimeContext(instant = new Date(), timezone) {
50
+ try {
51
+ const zone = timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone;
52
+ if (!zone)
53
+ throw new Error('Local timezone is unavailable.');
54
+ const parts = new Intl.DateTimeFormat('en-US', {
55
+ timeZone: zone,
56
+ year: 'numeric',
57
+ month: '2-digit',
58
+ day: '2-digit'
59
+ }).formatToParts(instant);
60
+ const value = (kind) => parts.find((part) => part.type === kind)?.value;
61
+ return {
62
+ currentDate: `${value('year')}-${value('month')}-${value('day')}`,
63
+ timezone: zone
64
+ };
65
+ }
66
+ catch {
67
+ return { currentDate: instant.toISOString().slice(0, 10), timezone: 'Etc/UTC' };
68
+ }
69
+ }
package/dist/sdk/agent.js CHANGED
@@ -19,7 +19,7 @@ import { buildSystemPrompt, MAR_AGENT_PROMPT_VERSION } from '../prompts/index.js
19
19
  import { buildEnvironmentContext } from '../prompts/core.js';
20
20
  import { modelOutputContinuationMessage } from '../prompts/output.js';
21
21
  import { retainedSessionResourcesSnapshot, retainedSessionResourcesUpdate } from '../prompts/resources.js';
22
- import { environmentContextUpdate, restoreEnvironmentState } from '../runtime/environment-context.js';
22
+ import { currentLocalTimeContext, environmentContextUpdate, restoreEnvironmentState } from '../runtime/environment-context.js';
23
23
  import { executionBudgetEnvironmentEntry } from '../prompts/execution-budget.js';
24
24
  import { childSubagentInstruction } from '../prompts/subagent.js';
25
25
  import { sessionTitlePrompt } from '../prompts/title.js';
@@ -152,6 +152,10 @@ export async function createMarAgentWithAdapter(options) {
152
152
  if ([...active.keys()].some((key) => key.startsWith(`${sessionId}:`)))
153
153
  throw new MarAgentError('MAR_AGENT_EXECUTION_ACTIVE', 'Session already has an active execution.');
154
154
  const executionId = randomUUID(), turnId = internal.turnId ?? randomUUID(), queue = new AsyncQueue(), controller = new AbortController();
155
+ let executionEnvironment = {
156
+ ...currentEnvironment,
157
+ ...currentLocalTimeContext()
158
+ };
155
159
  const executionModels = models;
156
160
  const executionDefaultModelId = defaultModelId;
157
161
  const executionModelGeneration = modelGeneration;
@@ -287,6 +291,7 @@ export async function createMarAgentWithAdapter(options) {
287
291
  includeImages: mode !== 'compact'
288
292
  });
289
293
  const messages = restored.messages;
294
+ let recordedEnvironment = restored.environmentState;
290
295
  let projectedExecutionBudgetStage;
291
296
  const appendExecutionBudgetEnvironment = () => {
292
297
  const currentStage = rolloutBudget?.active ? rolloutBudget.stage : 'inactive';
@@ -299,7 +304,7 @@ export async function createMarAgentWithAdapter(options) {
299
304
  (currentStage === 'inactive' && previousStage === 'normal'))
300
305
  return;
301
306
  const entry = executionBudgetEnvironmentEntry(currentStage === 'normal' ? 'inactive' : currentStage);
302
- messages.push(environmentContextUpdate(currentEnvironment, currentEnvironment, [entry]));
307
+ messages.push(environmentContextUpdate(executionEnvironment, executionEnvironment, [entry]));
303
308
  };
304
309
  const appendMailboxMessages = async () => {
305
310
  let appended = false;
@@ -324,16 +329,17 @@ export async function createMarAgentWithAdapter(options) {
324
329
  return appended;
325
330
  };
326
331
  const recordEnvironment = async () => {
327
- const message = environmentContextUpdate(currentEnvironment, restored.environmentState);
332
+ const message = environmentContextUpdate(executionEnvironment, recordedEnvironment);
328
333
  if (!message)
329
334
  return;
330
335
  await store.append(sessionId, {
331
336
  type: 'context.environment',
332
- payload: { version: 1, state: currentEnvironment },
337
+ payload: { version: 1, state: executionEnvironment },
333
338
  executionId,
334
339
  turnId
335
340
  });
336
341
  messages.push(message);
342
+ recordedEnvironment = executionEnvironment;
337
343
  };
338
344
  let compactionUserMessages = [
339
345
  ...restored.userMessages,
@@ -725,7 +731,7 @@ export async function createMarAgentWithAdapter(options) {
725
731
  summary: compactSummary,
726
732
  replacementHistory,
727
733
  automatic: true,
728
- environment: currentEnvironment,
734
+ environment: executionEnvironment,
729
735
  modelId: selectedModel.id,
730
736
  contextWindowTokens: selectedModel.contextWindowTokens,
731
737
  ...(latestUsage === undefined ? {} : { usage: latestUsage }),
@@ -733,8 +739,9 @@ export async function createMarAgentWithAdapter(options) {
733
739
  turnId
734
740
  });
735
741
  contextGc.reset();
736
- messages.splice(0, messages.length, environmentContextUpdate(currentEnvironment), ...compactedHistoryMessages(replacementHistory));
742
+ messages.splice(0, messages.length, environmentContextUpdate(executionEnvironment), ...compactedHistoryMessages(replacementHistory));
737
743
  projectedExecutionBudgetStage = undefined;
744
+ recordedEnvironment = executionEnvironment;
738
745
  compactionUserMessages = replacementHistory
739
746
  .filter((message) => message.kind === 'user_input')
740
747
  .map((message) => message.content);
@@ -780,6 +787,10 @@ export async function createMarAgentWithAdapter(options) {
780
787
  let incompleteToolCall = false;
781
788
  await ensureContextBudget();
782
789
  appendExecutionBudgetEnvironment();
790
+ if (mode !== 'compact') {
791
+ executionEnvironment = { ...currentEnvironment, ...currentLocalTimeContext() };
792
+ await recordEnvironment();
793
+ }
783
794
  const toolsAllowed = mode !== 'compact' && (!rolloutBudget?.active || rolloutBudget.stage !== 'exhausted');
784
795
  const roundTools = mode === 'compact' ? executionTools : toolsAllowed ? executionTools : [];
785
796
  const systemPrompt = mode === 'compact'
@@ -1191,6 +1202,7 @@ export async function createMarAgentWithAdapter(options) {
1191
1202
  });
1192
1203
  messages.splice(0, messages.length, ...refreshed.messages);
1193
1204
  projectedExecutionBudgetStage = undefined;
1205
+ recordedEnvironment = refreshed.environmentState;
1194
1206
  compactionUserMessages = [...refreshed.userMessages];
1195
1207
  agentInstructionInsertIndex =
1196
1208
  refreshed.currentTurnUserIndex ?? Math.max(0, messages.length - 1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myagentroam/agent",
3
- "version": "0.9.125",
3
+ "version": "0.9.127",
4
4
  "description": "Embeddable MAR coding agent SDK and CLI.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",