feat(core): Make sub-agents aware of the current time on instance AI (no-changelog) (#28809)

This commit is contained in:
Jaakko Husso
2026-04-22 06:53:32 +00:00
committed by GitHub
parent 0e838deab2
commit 08949a1ac9
5 changed files with 16 additions and 4 deletions
@@ -1,6 +1,7 @@
import { Agent } from '@mastra/core/agent';
import type { ToolsInput } from '@mastra/core/agent';
import { getDateTimeSection } from './system-prompt';
import { buildAgentTraceInputs, mergeTraceRunInputs } from '../tracing/langsmith-tracing';
import type { InstanceAiTraceRun, ModelConfig } from '../types';
@@ -17,6 +18,9 @@ export interface SubAgentOptions {
modelId: ModelConfig;
/** Optional trace run to annotate with the sub-agent's static config */
traceRun?: InstanceAiTraceRun;
/** IANA time zone for the current user — used to render the datetime section so
* the sub-agent resolves "now" consistently with the orchestrator. */
timeZone?: string;
}
/** Hard protocol injected into every sub-agent — cannot be overridden by orchestrator instructions. */
@@ -44,8 +48,9 @@ Keep diagnostics to 2-3 sentences maximum. Omit entirely when the task succeeded
export { SUB_AGENT_PROTOCOL };
function buildSubAgentPrompt(role: string, instructions: string): string {
function buildSubAgentPrompt(role: string, instructions: string, timeZone?: string): string {
return `${SUB_AGENT_PROTOCOL}
${getDateTimeSection(timeZone)}
You are a sub-agent with the role: ${role}.
@@ -54,9 +59,9 @@ ${instructions}`;
}
export function createSubAgent(options: SubAgentOptions): Agent {
const { agentId, role, instructions, tools, modelId, traceRun } = options;
const { agentId, role, instructions, tools, modelId, traceRun, timeZone } = options;
const systemPrompt = buildSubAgentPrompt(role, instructions);
const systemPrompt = buildSubAgentPrompt(role, instructions, timeZone);
const agent = new Agent({
id: agentId,
@@ -17,7 +17,7 @@ interface SystemPromptOptions {
branchReadOnly?: boolean;
}
function getDateTimeSection(timeZone?: string): string {
export function getDateTimeSection(timeZone?: string): string {
const now = timeZone ? DateTime.now().setZone(timeZone) : DateTime.now();
const isoTime = now.toISO({ includeOffset: true });
const tzLabel = timeZone ? ` (timezone: ${timeZone})` : '';
@@ -184,6 +184,7 @@ export async function startDetachedDelegateTask(
tools: tracedTools,
modelId: context.modelId,
traceRun: traceContext?.actorRun,
timeZone: context.timeZone,
});
registerWithMastra(subAgentId, subAgent, context.storage);
@@ -293,6 +294,7 @@ export function createDelegateTool(context: OrchestrationContext) {
tools: tracedTools,
modelId: context.modelId,
traceRun,
timeZone: context.timeZone,
});
registerWithMastra(subAgentId, subAgent, context.storage);
+3
View File
@@ -859,6 +859,9 @@ export interface OrchestrationContext {
/** Summaries of currently running background tasks in this thread.
* Used to give sub-agents thread-state awareness (what else is happening). */
getRunningTaskSummaries?: () => Array<{ taskId: string; role: string; goal?: string }>;
/** IANA time zone for the current user (e.g. "Europe/Helsinki"). Propagated to sub-agents
* so they can resolve "now" consistently with the orchestrator. */
timeZone?: string;
}
// ── Agent factory options ────────────────────────────────────────────────────
@@ -1292,6 +1292,7 @@ export class InstanceAiService {
abortSignal,
taskStorage,
researchMode,
timeZone: this.defaultTimeZone,
browserMcpConfig: this.instanceAiConfig.browserMcp
? { name: 'chrome-devtools', command: 'npx', args: ['-y', 'chrome-devtools-mcp@latest'] }
: undefined,
@@ -1611,6 +1612,7 @@ export class InstanceAiService {
// Make the current user message available to sub-agents (e.g. planner)
// since memory.recall() only returns previously-saved messages.
orchestrationContext.currentUserMessage = message;
orchestrationContext.timeZone = timeZone ?? this.defaultTimeZone;
// Thread attachments into the domain context so parse-file can access them
if (attachments && attachments.length > 0) {