mirror of
https://github.com/lobehub/lobehub
synced 2026-04-21 09:37:28 +00:00
🐛 fix: inject timezone and cron jobs list into cron tool system prompt (#14012)
* 🐛 fix: inject timezone and cron jobs list into cron tool system prompt Add {{timezone}} to cron systemRole session_context so the model knows the user's local timezone when creating scheduled tasks. Wire up the {{CRON_JOBS_LIST}} placeholder that was already referenced in the systemRole but never populated — now fetches the agent's existing cron jobs via tRPC and injects them, following the same pattern as CREDS_LIST. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🐛 fix: limit cron jobs context to 4 items to save context window Only inject a preview of up to 4 cron jobs into the system prompt. When there are more, append a hint directing the model to call listCronJobs API for the full list. This avoids bloating the context window for agents with many scheduled tasks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ca47d972a4
commit
665b482390
4 changed files with 70 additions and 0 deletions
25
packages/builtin-tool-cron/src/helpers.ts
Normal file
25
packages/builtin-tool-cron/src/helpers.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import type { CronJobSummaryForContext } from './types';
|
||||
|
||||
const formatCronJob = (job: CronJobSummaryForContext): string => {
|
||||
const status = job.enabled ? 'enabled' : 'disabled';
|
||||
const execInfo =
|
||||
job.remainingExecutions != null ? `${job.remainingExecutions} remaining` : 'unlimited';
|
||||
const lastRun = job.lastExecutedAt ?? 'never';
|
||||
const desc = job.description ? ` - ${job.description}` : '';
|
||||
|
||||
return ` - ${job.name || 'Unnamed'} (id: ${job.id}): ${job.cronPattern} [${job.timezone}] [${status}, ${execInfo}, ${job.totalExecutions} completed, last run: ${lastRun}]${desc}`;
|
||||
};
|
||||
|
||||
export const generateCronJobsList = (jobs: CronJobSummaryForContext[], total?: number): string => {
|
||||
if (jobs.length === 0) {
|
||||
return 'No scheduled tasks configured for this agent.';
|
||||
}
|
||||
|
||||
const lines = jobs.map(formatCronJob);
|
||||
|
||||
if (total && total > jobs.length) {
|
||||
lines.push(` (showing ${jobs.length} of ${total} tasks — use listCronJobs to see all)`);
|
||||
}
|
||||
|
||||
return lines.join('\n');
|
||||
};
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
export { CronExecutionRuntime, type ICronService } from './ExecutionRuntime';
|
||||
export { generateCronJobsList } from './helpers';
|
||||
export { CronIdentifier, CronManifest } from './manifest';
|
||||
export { systemPrompt } from './systemRole';
|
||||
export {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ export const systemPrompt = `You have access to a LobeHub Scheduled Tasks Tool.
|
|||
Current user: {{username}}
|
||||
Session date: {{date}}
|
||||
Current agent: {{agent_id}}
|
||||
User timezone: {{timezone}}
|
||||
</session_context>
|
||||
|
||||
<existing_scheduled_tasks>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,11 @@ import { LobeActivatorIdentifier } from '@lobechat/builtin-tool-activator';
|
|||
import { AgentBuilderIdentifier } from '@lobechat/builtin-tool-agent-builder';
|
||||
import { AgentManagementIdentifier } from '@lobechat/builtin-tool-agent-management';
|
||||
import { CredsIdentifier, type CredSummary, generateCredsList } from '@lobechat/builtin-tool-creds';
|
||||
import {
|
||||
CronIdentifier,
|
||||
type CronJobSummaryForContext,
|
||||
generateCronJobsList,
|
||||
} from '@lobechat/builtin-tool-cron';
|
||||
import { GroupAgentBuilderIdentifier } from '@lobechat/builtin-tool-group-agent-builder';
|
||||
import { GTDIdentifier } from '@lobechat/builtin-tool-gtd';
|
||||
import { WebOnboardingIdentifier } from '@lobechat/builtin-tool-web-onboarding';
|
||||
|
|
@ -377,6 +382,42 @@ export const contextEngineering = async ({
|
|||
}
|
||||
}
|
||||
|
||||
// Resolve cron jobs context for cron tool
|
||||
// Only inject a small preview (up to 4) to save context window;
|
||||
// the model can call listCronJobs API for the full list.
|
||||
const isCronEnabled = tools?.includes(CronIdentifier) ?? false;
|
||||
let cronJobsList: CronJobSummaryForContext[] | undefined;
|
||||
let cronJobsTotal = 0;
|
||||
|
||||
if (isCronEnabled && agentId) {
|
||||
try {
|
||||
const cronResult = await lambdaClient.agentCronJob.list.query({ agentId, limit: 4 });
|
||||
const jobs = (cronResult as any)?.data ?? [];
|
||||
cronJobsTotal = (cronResult as any)?.pagination?.total ?? jobs.length;
|
||||
cronJobsList = jobs.map(
|
||||
(job: any): CronJobSummaryForContext => ({
|
||||
cronPattern: job.cronPattern,
|
||||
description: job.description,
|
||||
enabled: job.enabled,
|
||||
id: job.id,
|
||||
lastExecutedAt: job.lastExecutedAt,
|
||||
name: job.name,
|
||||
remainingExecutions: job.remainingExecutions,
|
||||
timezone: job.timezone ?? 'UTC',
|
||||
totalExecutions: job.totalExecutions ?? 0,
|
||||
}),
|
||||
);
|
||||
log(
|
||||
'Cron jobs context resolved: count=%d, total=%d',
|
||||
cronJobsList?.length ?? 0,
|
||||
cronJobsTotal,
|
||||
);
|
||||
} catch (error) {
|
||||
// Silently fail - cron context is optional
|
||||
log('Failed to resolve cron jobs context:', error);
|
||||
}
|
||||
}
|
||||
|
||||
const userMemoryConfig =
|
||||
enableUserMemories && userMemoryData
|
||||
? {
|
||||
|
|
@ -694,6 +735,8 @@ export const contextEngineering = async ({
|
|||
...VARIABLE_GENERATORS,
|
||||
// NOTICE: required by builtin-tool-creds/src/systemRole.ts
|
||||
CREDS_LIST: () => (credsList ? generateCredsList(credsList) : ''),
|
||||
// NOTICE: required by builtin-tool-cron/src/systemRole.ts
|
||||
CRON_JOBS_LIST: () => (cronJobsList ? generateCronJobsList(cronJobsList, cronJobsTotal) : ''),
|
||||
// NOTICE(@nekomeowww): required by builtin-tool-memory/src/systemRole.ts
|
||||
memory_effort: () => (userMemoryConfig ? (memoryContext?.effort ?? '') : ''),
|
||||
// Current agent + topic identity — referenced by the LobeHub builtin
|
||||
|
|
|
|||
Loading…
Reference in a new issue