@agent-assistant/proactive
状态 : 执行-准备
版本 : 0.1.0(1.0前,临时)
谱: docs/specs/v1-proactive-spec.md
实施计划: docs/architecture/v1-proactive-implementation-plan.md
此套件会做什么
@agent-assistant/proactive 是主动助理行为的决策层——任何从当前转弯时没有直接用户消息的助理动作.
它规定:
- 主动引擎 评估后续规则,对照会议背景观察规则,适用压制政策,并返回结构化决定
- 后续规则评价 ——规则起火,压制或被冷却/最大计数/用户活动检查所压制
- 提醒政策 ——可配置
maxReminders, (中文(简体) ),cooldownMs,以及suppressWhenActive根据规则 - 遵守规则 长期监测规则,在每次评价后重新安排时间;暂停、恢复和取消生命周期方法
- 调度器Binding 接口 – 与外部调度基础设施(中继器)的合同薄;此套件不拥有或包接中继器
- 在记忆中SchedulerBinding ——带有手动触发器的测试适配器;测试不需要外部基础设施
- 后续证据源接口 ——规则条件的可选插件证据注入(如内存条目)
这个软件包是 没有 拥有调度基础设施,会话生命周期,消息发送,或特定域的规则逻辑. 所有这一切都留在产品代码或其他包.
安装
npm install @agent-assistant/proactive
没有 @agent-assistant/* 运行时间依赖。 仅 nanoid 运行时需要.
快速启动
import {
createProactiveEngine,
InMemorySchedulerBinding,
} from '@agent-assistant/proactive';
import type { FollowUpRule } from '@agent-assistant/proactive';
// Wire a scheduler binding (InMemorySchedulerBinding for tests/dev)
const schedulerBinding = new InMemorySchedulerBinding();
const engine = createProactiveEngine({
schedulerBinding,
defaultReminderPolicy: {
maxReminders: 3,
cooldownMs: 3_600_000, // 1 hour
suppressWhenActive: true,
},
});
// Register a follow-up rule (stale-thread pattern)
const staleThreadRule: FollowUpRule = {
id: 'stale-thread',
description: 'Follow up if the session has been silent for more than 24 hours',
condition: (ctx) => {
const inactiveMs =
new Date(ctx.scheduledAt).getTime() - new Date(ctx.lastActivityAt).getTime();
return inactiveMs > 24 * 60 * 60 * 1000;
},
policy: {
maxReminders: 2,
cooldownMs: 24 * 60 * 60 * 1000,
},
routingHint: 'cheap',
messageTemplate: 'Checking in — any updates on this thread?',
};
engine.registerFollowUpRule(staleThreadRule);
处理器中的使用
主动软件包没有登记能力处理器。 产品自己写:
// In your assistant definition (product code)
const definition = {
capabilities: {
proactive: async (message, context) => {
const wakeUpContext = message.payload; // parsed from the synthetic wake-up message
// Fetch session state from your session store
const session = await context.sessionStore.get(wakeUpContext.sessionId);
// Evaluate follow-up rules
const decisions = await engine.evaluateFollowUp({
sessionId: wakeUpContext.sessionId,
scheduledAt: wakeUpContext.scheduledAt,
lastActivityAt: session.lastActivityAt,
});
for (const decision of decisions) {
if (decision.action === 'fire') {
await context.runtime.emit({
sessionId: decision.sessionId,
text: decision.messageTemplate ?? 'Following up.',
});
}
}
},
},
};
后续规则
规则由产品提供。 引擎处理手表规则 通过 SchedulerBinding 和记念的状态。 后续时间安排由产品自主.
interface FollowUpRule {
id: string;
condition(ctx: FollowUpEvaluationContext, evidence: EvidenceEntry[]): boolean | Promise<boolean>;
description?: string;
policy?: ReminderPolicy; // overrides engine default when present
routingHint?: 'cheap' | 'fast' | 'deep'; // defaults to 'cheap'
messageTemplate?: string;
}
禁止令 :
- 用户在唤醒安排后开始活动( U)
lastActivityAt > scheduledAt(中文(简体) ) - 达到的最大提醒
(sessionId, ruleId)组合 - 自上次提醒以来, 冷却窗口没有通过
- 条件函数返回为假
初相匹配压制取胜. 如果没有匹配,决定是 fire。 。 。 .
观察规则
守望规则是长期运行的监视器,在每次评价后都会重新安排自己——无论条件是否被触发.
engine.registerWatchRule({
id: 'unreviewed-pr',
description: 'Alert if a PR has been open without review for over 2 hours',
condition: async (ctx) => {
// product fetches PR state from its own store
return myStore.hasUnreviewedPRsOlderThan(2 * 60 * 60 * 1000);
},
action: { type: 'notify_channel', payload: { channel: 'eng-alerts' } },
intervalMs: 30 * 60 * 1000, // check every 30 minutes
});
// Lifecycle
engine.pauseWatchRule('unreviewed-pr');
engine.resumeWatchRule('unreviewed-pr');
engine.cancelWatchRule('unreviewed-pr'); // permanent; re-register to restart
// List statuses
const statuses = engine.listWatchRules();
// [{ rule, status: 'active' | 'paused' | 'cancelled', lastEvaluatedAt, nextWakeUpBindingId }]
// Evaluate (called from your proactive capability handler after each wake-up)
const triggers = await engine.evaluateWatchRules({
ruleId: wakeUpContext.ruleId,
scheduledAt: wakeUpContext.scheduledAt,
metadata: wakeUpContext.metadata,
});
for (const trigger of triggers) {
await handleWatchAction(trigger.action, trigger.context);
}
调度器绑定
这个 SchedulerBinding 接口将引擎与调度基础设施脱钩.
interface SchedulerBinding {
requestWakeUp(at: Date, context: WakeUpContext): Promise<string>; // returns bindingId
cancelWakeUp(bindingId: string): Promise<void>;
}
测试和地方开发: 使用内置 InMemorySchedulerBinding数字 :
const binding = new InMemorySchedulerBinding();
// Inspect pending wake-ups
console.log(binding.pendingWakeUps); // Map<bindingId, { at, context }>
// Manually fire a wake-up in tests
const context = await binding.trigger(bindingId);
用于生产: 执行 SchedulerBinding 对你的中继客户端。 积极主动的一揽子计划没有实施或推动中继子集成——即产品/创始关切.
证据来源
可选的 给最近内存条目或其他上下文提供规则条件的证据源线:
const evidenceSource = {
getRecentEntries: (sessionId, opts) =>
memoryStore.retrieve({ scope: { kind: 'session', sessionId }, limit: opts?.limit }),
};
const engine = createProactiveEngine({ schedulerBinding, evidenceSource });
如果配置, 引擎调用 getRecentEntries 单次 evaluateFollowUp 调用(该调用中所有规则共用)。 若为 context.evidence 被预选并提供了, 源根本没有调用.
如果不配置, 条件函数接收到一个空证据阵列 .
提醒州管理层
提醒状态为内存并按键 (sessionId, ruleId)。 。 。 .
// Clear state for a specific rule in a session (e.g., when user resolves the thread)
engine.resetReminderState('session-abc', 'stale-thread');
// Clear all reminder state for a session (e.g., on session close)
engine.resetReminderState('session-abc');
此套件以外的内容
| 关切 | 它的栖息地点 |
|---|---|
| 时间安排基础设施(计时器、克龙、调度) | 中继基础( 中继) |
| 特定领域的规则定义 | 产品重置 |
| 特定产品计时阈值 | 产品配置 |
| 内存持久性 | @agent-assistant/memory (通过) FollowUpEvidenceSource(中文(简体) ) |
| 届会周期 | @agent-assistant/sessions |
| 发送出境信息 | @agent-assistant/surfaces + 中继运行时间 |
| 积极行动的跨部门协调 | @agent-assistant/coordination (v1.2) (中文(简体) ) |
| 主动行动率限制/预算 | @agent-assistant/policy (v2级) |
软件包结构
packages/proactive/
package.json — nanoid runtime dep only
tsconfig.json
src/
types.ts — all exported types, interfaces, error classes
proactive.ts — createProactiveEngine factory and all engine logic
index.ts — public re-exports
proactive.test.ts — 45 tests
README.md
宣传 包接 数字 完成