@dsh-enhanced/assistant-proactive 0.1.30

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/lib/index.js ADDED
@@ -0,0 +1,138 @@
1
+ import { Context, Service } from '@deepseek-ai/cordis';
2
+ import { defineTool } from '@deepseek-ai/dsh-tools';
3
+ import Schema from '@deepseek-ai/schemastery';
4
+ import { acceptanceDigest } from '@dsh-enhanced/task-acceptance-contract';
5
+ import { homedir } from 'node:os';
6
+ import { join } from 'node:path';
7
+ import { OpportunityEngine, validateProfile } from './engine.js';
8
+ import { reminderText, reminderExpiresAt } from './reminder.js';
9
+ import { PreparationRuntime } from './preparation.js';
10
+ import { PreparationStore } from './preparation-store.js';
11
+ import { version } from './version.js';
12
+ export const name = 'dsh-enhanced-assistant-proactive';
13
+ export { version, OpportunityEngine, validateProfile };
14
+ const integer = (max = 1_000_000_000) => Schema.number().step(1).min(0).max(max).required();
15
+ export const Config = Schema.object({
16
+ databasePath: Schema.string().default(join(homedir(), '.dsh', 'assistant-proactive.sqlite')),
17
+ profiles: Schema.array(Schema.object({
18
+ preparation: Schema.union([Schema.object({ provider: Schema.string().required(), model: Schema.string().required(), budgetId: Schema.string().required(), maxOutputTokens: Schema.number().step(1).min(1).max(32_768).required(), timeoutMs: Schema.number().step(1).min(1_000).max(300_000).required() })]),
19
+ id: Schema.string().required(), mode: Schema.union(['prepare', 'remind', 'execute']).required(),
20
+ expectedBenefit: integer(), successPpm: integer(1_000_000), executionCost: integer(), interruptionCost: integer(), possibleLoss: integer(),
21
+ minimumUtility: integer(),
22
+ mergeWindowMs: integer(), cooldownMs: integer(), rejectionCooldownMs: integer(),
23
+ quietHours: Schema.union([Schema.object({ timezone: Schema.string().required(), startMinute: integer(1439), endMinute: integer(1439) })]),
24
+ maxDecisionsPerGoal: integer(), maxExecutionsPerGoal: integer(), maxRemindersPerGoal: integer(),
25
+ })).default([]),
26
+ });
27
+ /** This optional decision gate cannot resume a goal or grant tool/route authority. */
28
+ export class AssistantProactiveService extends Service {
29
+ static Config = Config;
30
+ #preparations;
31
+ #engine;
32
+ #profiles = new Map();
33
+ #active = true;
34
+ constructor(ctx, config = {}) {
35
+ super(ctx, 'assistantProactive');
36
+ for (const input of config.profiles ?? []) {
37
+ const profile = validateProfile(input);
38
+ if (this.#profiles.has(profile.id))
39
+ throw new Error('assistant-proactive: duplicate profile');
40
+ this.#profiles.set(profile.id, profile);
41
+ }
42
+ this.#engine = new OpportunityEngine(config.databasePath ?? join(homedir(), '.dsh', 'assistant-proactive.sqlite'), [...this.#profiles.values()]);
43
+ ctx.effect(() => () => { this.#active = false; this.#engine.close(); }, 'assistant-proactive.store');
44
+ const preparationPath = config.databasePath === ':memory:' ? ':memory:' : `${config.databasePath ?? join(homedir(), '.dsh', 'assistant-proactive.sqlite')}.preparations`;
45
+ this.#preparations = new PreparationRuntime(ctx, new PreparationStore(preparationPath));
46
+ ctx.inject(['tools', 'agents', 'assistantDelivery', 'assistantPolicy'], runtime => {
47
+ const output = {
48
+ schema: { type: 'object', additionalProperties: false, properties: { context: { type: 'string', required: true } } },
49
+ render: (_args, value) => [{ type: 'text', text: value.context }],
50
+ };
51
+ runtime.tools.register(defineTool({
52
+ name: 'proactive_status',
53
+ description: 'Inspect owner-scoped event opportunity decisions and operator utility estimates. Preparation may include a persisted model draft when explicitly configured. Drafts are unverified and do not mean the original goal was executed.',
54
+ parameters: { goal_id: { type: 'string' } }, output,
55
+ execute: async (args, execution) => { return { context: JSON.stringify(this.inspect(execution.agent, args.goal_id)) }; },
56
+ }));
57
+ runtime.tools.register(defineTool({
58
+ name: 'proactive_feedback',
59
+ description: 'Record current authenticated owner feedback on an opportunity. Rejection starts a durable cooldown for subsequent decisions. Feedback grants no execution permission and does not undo an already dispatched goal.',
60
+ parameters: { decision_id: { type: 'string', required: true }, feedback: { type: 'string', enum: ['accepted', 'rejected'], required: true } }, output,
61
+ execute: async (args, execution) => { return { context: JSON.stringify(this.feedback(execution.agent, args.decision_id, args.feedback)) }; },
62
+ }));
63
+ });
64
+ }
65
+ assertProfile = (profileId) => {
66
+ if (!this.#active || !this.#profiles.has(profileId))
67
+ throw new Error('assistant-proactive: configured active opportunity profile required');
68
+ if (this.#profiles.get(profileId).preparation && !this.#preparations.available())
69
+ throw new Error('assistant-proactive: preparation services unavailable');
70
+ if (this.#profiles.get(profileId).mode === 'remind' && !this.#notificationPort())
71
+ throw new Error('assistant-proactive: reminder delivery service unavailable');
72
+ };
73
+ evaluate = (input) => {
74
+ this.assertProfile(input.profileId);
75
+ const evaluation = this.#engine.evaluate(input);
76
+ const decision = evaluation.decision;
77
+ if (evaluation.disposition === 'consume' && decision.mode === 'remind' && decision.state === 'decided') {
78
+ const delivery = this.#notificationPort();
79
+ if (!delivery)
80
+ throw new Error('assistant-proactive: reminder delivery service unavailable');
81
+ const profile = this.#engine.profileSnapshot(decision.scope, decision.goalId, decision.profileId);
82
+ const expiresAt = reminderExpiresAt(decision, profile);
83
+ if (Date.now() < expiresAt)
84
+ delivery.enqueueOwnerNotification({ sourceId: 'assistant-proactive/v1', ownerRouteId: decision.ownerRouteId, scope: decision.scope, sessionId: decision.sessionId, idempotencyKey: `proactive-reminder:${decision.id}`, text: reminderText(decision, profile), expiresAt });
85
+ }
86
+ if (evaluation.disposition === 'consume' && decision.mode === 'prepare' && decision.state === 'decided') {
87
+ const profile = this.#engine.profileSnapshot(decision.scope, decision.goalId, decision.profileId);
88
+ if (profile.preparation) {
89
+ this.#preparations.store.enqueue(decision, profile.preparation, reminderExpiresAt(decision, profile));
90
+ void this.#preparations.tick().catch(() => { });
91
+ }
92
+ }
93
+ return evaluation;
94
+ };
95
+ #notificationPort() {
96
+ const delivery = this.ctx.get('assistantDelivery');
97
+ return typeof delivery?.enqueueOwnerNotification === 'function' ? delivery : undefined;
98
+ }
99
+ closeWait = (waitId, scope, reason) => {
100
+ if (!this.#active)
101
+ throw new Error('assistant-proactive: disposed');
102
+ this.#engine.closeWait(waitId, scope, reason);
103
+ this.#preparations.store.cancelWait(waitId, scope);
104
+ };
105
+ #scope(agent, feedback) {
106
+ if (!this.#active)
107
+ throw new Error('assistant-proactive: disposed');
108
+ if (!agent || this.ctx.get('agents')?.get(agent.id) !== agent)
109
+ throw new Error('assistant-proactive: exact live agent required');
110
+ const delivery = this.ctx.get('assistantDelivery');
111
+ const owner = delivery?.preferencePrincipalForAgent(agent);
112
+ if (!owner || owner.scope.workspace !== agent.session.header.cwd || owner.scope.preset !== agent.session.header.agentPreset)
113
+ throw new Error('assistant-proactive: authenticated owner required');
114
+ const scope = { principalId: owner.principalId, ...owner.principalLineage, workspace: owner.scope.workspace, preset: owner.scope.preset };
115
+ if (feedback) {
116
+ const turn = delivery?.currentPreferenceTurn(agent);
117
+ if (!turn || acceptanceDigest({ principalId: turn.principalId, ...turn.principalLineage, workspace: turn.scope.workspace, preset: turn.scope.preset }) !== acceptanceDigest(scope))
118
+ throw new Error('assistant-proactive: current authenticated owner turn required');
119
+ }
120
+ const policy = this.ctx.get('assistantPolicy');
121
+ if (policy?.authorizeAgent(agent, feedback ? 'feedback' : 'inspect', { kind: 'goal', id: 'proactive-opportunities' }).effect !== 'allow')
122
+ throw new Error('assistant-proactive: policy denied');
123
+ return scope;
124
+ }
125
+ inspect = (agent, goalId) => {
126
+ return this.#engine.list(this.#scope(agent, false), goalId).map(decision => {
127
+ const preparation = this.#preparations.store.get(decision.id);
128
+ return preparation ? { ...decision, preparation: { state: preparation.state, reason: preparation.reason, updatedAt: preparation.updatedAt,
129
+ ...(preparation.result ? { output: preparation.result.output, sessionId: preparation.result.sessionId, usage: preparation.result.usage, diagnostic: preparation.result.diagnostic, verified: false } : {}) } } : decision;
130
+ });
131
+ };
132
+ reconcilePreparations = () => this.#preparations.tick();
133
+ feedback = (agent, id, feedback) => { const decision = this.#engine.feedback(id, this.#scope(agent, true), feedback); if (feedback === 'rejected')
134
+ this.#preparations.store.cancel(id); return decision; };
135
+ }
136
+ export function apply(ctx, config = {}) { new AssistantProactiveService(ctx, config); }
137
+ export default { name, Config, apply };
138
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAGnD,OAAO,MAAM,MAAM,0BAA0B,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEhE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,MAAM,CAAC,MAAM,IAAI,GAAG,kCAAkC,CAAA;AACtD,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,CAAA;AAItD,MAAM,OAAO,GAAG,CAAC,GAAG,GAAG,aAAa,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAA;AAC3F,MAAM,CAAC,MAAM,MAAM,GAAmB,MAAM,CAAC,MAAM,CAAC;IAClD,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,4BAA4B,CAAC,CAAC;IAC5F,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;QACnC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5S,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE;QAC/F,eAAe,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE;QAC1I,cAAc,EAAE,OAAO,EAAE;QACzB,aAAa,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,mBAAmB,EAAE,OAAO,EAAE;QAC/E,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACzI,mBAAmB,EAAE,OAAO,EAAE,EAAE,oBAAoB,EAAE,OAAO,EAAE,EAAE,mBAAmB,EAAE,OAAO,EAAE;KAChG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAChB,CAAC,CAAA;AAGF,sFAAsF;AACtF,MAAM,OAAO,yBAA0B,SAAQ,OAAO;IACpD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAA;IACb,aAAa,CAAoB;IACjC,OAAO,CAAmB;IAC1B,SAAS,GAAG,IAAI,GAAG,EAA8B,CAAA;IAC1D,OAAO,GAAG,IAAI,CAAA;IACd,YAAY,GAAY,EAAE,SAAiB,EAAE;QAC3C,KAAK,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAA;QAChC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;YAC1C,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;YACtC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;YAC7F,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;QACzC,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,4BAA4B,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;QAChJ,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA,CAAC,CAAC,EAAE,2BAA2B,CAAC,CAAA;QACnG,MAAM,eAAe,GAAG,MAAM,CAAC,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,4BAA4B,CAAC,eAAe,CAAA;QACxK,IAAI,CAAC,aAAa,GAAG,IAAI,kBAAkB,CAAC,GAAG,EAAE,IAAI,gBAAgB,CAAC,eAAe,CAAC,CAAC,CAAA;QACvF,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,EAAE;YAChF,MAAM,MAAM,GAAG;gBACb,MAAM,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,oBAAoB,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE;gBACtI,MAAM,EAAE,CAAC,KAAc,EAAE,KAA0B,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;aAChG,CAAA;YACV,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;gBAChC,IAAI,EAAE,kBAAkB;gBACxB,WAAW,EAAE,oOAAoO;gBACjP,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM;gBACnD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAA,CAAC,CAAC;aACxH,CAAC,CAAC,CAAA;YACH,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;gBAChC,IAAI,EAAE,oBAAoB;gBAC1B,WAAW,EAAE,oNAAoN;gBACjO,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM;gBACrJ,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAmC,CAAC,CAAC,EAAE,CAAA,CAAC,CAAC;aACvK,CAAC,CAAC,CAAA;QACL,CAAC,CAAC,CAAA;IACJ,CAAC;IACD,aAAa,GAAG,CAAC,SAAiB,EAAQ,EAAE;QAC1C,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAA;QAC3I,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;QAC3J,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAA;IAClK,CAAC,CAAA;IACD,QAAQ,GAAG,CAAC,KAAuB,EAAE,EAAE;QACrC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QACnC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QAC/C,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAA;QACpC,IAAI,UAAU,CAAC,WAAW,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACvG,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAA;YACzC,IAAI,CAAC,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAA;YAC5F,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAA;YACjG,MAAM,SAAS,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YACtD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;gBAAE,QAAQ,CAAC,wBAAwB,CAAC,EAAE,QAAQ,EAAE,wBAAwB,EAAE,YAAY,EAAE,QAAQ,CAAC,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,cAAc,EAAE,sBAAsB,QAAQ,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC,CAAA;QACzS,CAAC;QACD,IAAI,UAAU,CAAC,WAAW,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACxG,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAA;YACjG,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;gBACxB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,WAAW,EAAE,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAA;gBACrG,KAAK,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YAChD,CAAC;QACH,CAAC;QACD,OAAO,UAAU,CAAA;IACnB,CAAC,CAAA;IACD,iBAAiB;QACf,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAqD,CAAA;QACtG,OAAO,OAAO,QAAQ,EAAE,wBAAwB,KAAK,UAAU,CAAC,CAAC,CAAC,QAA4B,CAAC,CAAC,CAAC,SAAS,CAAA;IAC5G,CAAC;IACD,SAAS,GAAG,CAAC,MAAc,EAAE,KAAuB,EAAE,MAA+B,EAAQ,EAAE;QAC7F,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;QACnE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAC7C,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IACpD,CAAC,CAAA;IACD,MAAM,CAAC,KAAwB,EAAE,QAAiB;QAChD,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;QACnE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;QAChI,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAyC,CAAA;QAC1F,MAAM,KAAK,GAAG,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,CAAA;QAC1D,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW;YAAE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;QACjM,MAAM,KAAK,GAAG,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,gBAAgB,EAAE,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAA;QACzI,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,QAAQ,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAA;YACnD,IAAI,CAAC,IAAI,IAAI,gBAAgB,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,gBAAgB,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,KAAK,gBAAgB,CAAC,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAA;QACvQ,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAuC,CAAA;QACpF,IAAI,MAAM,EAAE,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,yBAAyB,EAAE,CAAC,CAAC,MAAM,KAAK,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;QAC/L,OAAO,KAAK,CAAA;IACd,CAAC;IACD,OAAO,GAAG,CAAC,KAAwB,EAAE,MAAe,EAAE,EAAE;QACtD,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;YACzE,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;YAC7D,OAAO,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,SAAS;oBACvI,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAA;QAC7N,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IACD,qBAAqB,GAAG,GAAkB,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAA;IACtE,QAAQ,GAAG,CAAC,KAAwB,EAAE,EAAU,EAAE,QAAiC,EAAE,EAAE,GAAG,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,KAAK,UAAU;QAAE,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,QAAQ,CAAA,CAAC,CAAC,CAAA;;AAE/P,MAAM,UAAU,KAAK,CAAC,GAAY,EAAE,SAAiB,EAAE,IAAU,IAAI,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA,CAAC,CAAC;AAC7G,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA"}
@@ -0,0 +1,39 @@
1
+ import type { OpportunityDecision, OpportunityScope, PreparationSettings } from './types.js';
2
+ export interface PreparationResult {
3
+ outcome: string;
4
+ output: string;
5
+ usage: Readonly<Record<string, unknown>>;
6
+ sessionId?: string;
7
+ quiescent?: boolean;
8
+ diagnostic?: Readonly<{
9
+ failureClass: string;
10
+ failurePhase: string;
11
+ failureCode: string;
12
+ }>;
13
+ }
14
+ export interface PreparationRecord {
15
+ id: string;
16
+ decision: OpportunityDecision;
17
+ settings: PreparationSettings;
18
+ state: 'queued' | 'running' | 'draft' | 'failed' | 'cancelled' | 'unknown';
19
+ createdAt: number;
20
+ updatedAt: number;
21
+ deadlineAt: number;
22
+ token?: string;
23
+ result?: PreparationResult;
24
+ reason?: string;
25
+ }
26
+ /** The preparation intent and result are private, durable data; neither is goal completion evidence. */
27
+ export declare class PreparationStore {
28
+ #private;
29
+ constructor(path: string);
30
+ enqueue(decision: OpportunityDecision, settings: PreparationSettings, deadlineAt?: number): PreparationRecord;
31
+ get(id: string): PreparationRecord | undefined;
32
+ pending(): PreparationRecord[];
33
+ claim(id: string): PreparationRecord | undefined;
34
+ finish(value: PreparationRecord, state: PreparationRecord['state'], result?: PreparationResult, reason?: string): void;
35
+ cancel(id: string): void;
36
+ cancelWait(waitId: string, scope: OpportunityScope): void;
37
+ close(): void;
38
+ }
39
+ //# sourceMappingURL=preparation-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preparation-store.d.ts","sourceRoot":"","sources":["../src/preparation-store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAE5F,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAClH,UAAU,CAAC,EAAE,QAAQ,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC3F;AACD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,mBAAmB,CAAA;IACxE,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAA;IAC1E,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACtH;AAED,wGAAwG;AACxG,qBAAa,gBAAgB;;gBAEf,IAAI,EAAE,MAAM;IAaxB,OAAO,CAAC,QAAQ,EAAE,mBAAmB,EAAE,QAAQ,EAAE,mBAAmB,EAAE,UAAU,SAAqB,GAAG,iBAAiB;IAYzH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAI9C,OAAO,IAAI,iBAAiB,EAAE;IAG9B,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAMhD,MAAM,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAKtH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIxB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAUzD,KAAK,IAAI,IAAI;CACd"}
@@ -0,0 +1,74 @@
1
+ import { DatabaseSync } from 'node:sqlite';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { acceptanceDigest } from '@dsh-enhanced/task-acceptance-contract';
4
+ import { privatePath } from './engine.js';
5
+ /** The preparation intent and result are private, durable data; neither is goal completion evidence. */
6
+ export class PreparationStore {
7
+ #db;
8
+ constructor(path) {
9
+ if (path !== ':memory:')
10
+ privatePath(path);
11
+ this.#db = new DatabaseSync(path);
12
+ this.#db.exec(`PRAGMA journal_mode=WAL; PRAGMA synchronous=FULL; PRAGMA busy_timeout=250;
13
+ CREATE TABLE IF NOT EXISTS proactive_preparations(id TEXT PRIMARY KEY, scope_key TEXT NOT NULL, goal_id TEXT NOT NULL, state TEXT NOT NULL, token TEXT, payload_json TEXT NOT NULL) STRICT;
14
+ CREATE INDEX IF NOT EXISTS proactive_preparations_scope ON proactive_preparations(scope_key,goal_id);`);
15
+ // A previous process may have dispatched a paid request. Never retry that
16
+ // uncertain call automatically; a concurrent opener fences its late result.
17
+ for (const row of this.#db.prepare("SELECT id FROM proactive_preparations WHERE state='running'").all()) {
18
+ const value = this.get(row.id);
19
+ this.#write({ ...value, state: 'unknown', reason: 'process-interrupted', updatedAt: Date.now() }, 'running');
20
+ }
21
+ }
22
+ enqueue(decision, settings, deadlineAt = decision.expiresAt) {
23
+ const existing = this.get(decision.id);
24
+ if (existing) {
25
+ if (acceptanceDigest([existing.decision, existing.settings, existing.deadlineAt]) !== acceptanceDigest([decision, settings, deadlineAt]))
26
+ throw new Error('assistant-proactive: preparation identity conflict');
27
+ return existing;
28
+ }
29
+ const value = { id: decision.id, decision, settings, deadlineAt, state: 'queued', createdAt: Date.now(), updatedAt: Date.now() };
30
+ this.#db.prepare('INSERT OR IGNORE INTO proactive_preparations VALUES(?,?,?,?,?,?)').run(value.id, acceptanceDigest(decision.scope), decision.goalId, value.state, null, JSON.stringify(value));
31
+ const saved = this.get(value.id);
32
+ if (acceptanceDigest([saved.decision, saved.settings, saved.deadlineAt]) !== acceptanceDigest([decision, settings, deadlineAt]))
33
+ throw new Error('assistant-proactive: preparation identity conflict');
34
+ return saved;
35
+ }
36
+ get(id) {
37
+ const row = this.#db.prepare('SELECT payload_json FROM proactive_preparations WHERE id=?').get(id);
38
+ return row === undefined ? undefined : JSON.parse(row.payload_json);
39
+ }
40
+ pending() {
41
+ return this.#db.prepare("SELECT payload_json FROM proactive_preparations WHERE state='queued' ORDER BY rowid LIMIT 32").all().map(row => JSON.parse(row.payload_json));
42
+ }
43
+ claim(id) {
44
+ const value = this.get(id);
45
+ if (!value || value.state !== 'queued')
46
+ return undefined;
47
+ const claimed = { ...value, state: 'running', token: randomUUID(), updatedAt: Date.now() };
48
+ return this.#write(claimed, 'queued') ? claimed : undefined;
49
+ }
50
+ finish(value, state, result, reason) {
51
+ const current = this.get(value.id);
52
+ if (current?.state !== 'running' || current.token !== value.token)
53
+ return;
54
+ this.#write({ ...current, state, updatedAt: Date.now(), ...(result ? { result } : {}), ...(reason ? { reason } : {}) }, 'running', value.token);
55
+ }
56
+ cancel(id) {
57
+ const value = this.get(id);
58
+ if (value && (value.state === 'queued' || value.state === 'running'))
59
+ this.#write({ ...value, state: 'cancelled', reason: 'owner-rejected', updatedAt: Date.now() }, value.state);
60
+ }
61
+ cancelWait(waitId, scope) {
62
+ for (const row of this.#db.prepare("SELECT payload_json FROM proactive_preparations WHERE scope_key=? AND state IN ('queued','running')").all(acceptanceDigest(scope))) {
63
+ const value = JSON.parse(row.payload_json);
64
+ if (value.decision.waitId === waitId)
65
+ this.#write({ ...value, state: 'cancelled', reason: 'wait-ended', updatedAt: Date.now() }, value.state);
66
+ }
67
+ }
68
+ #write(value, expected, token) {
69
+ return this.#db.prepare(`UPDATE proactive_preparations SET state=?,token=?,payload_json=? WHERE id=? AND state=?${token === undefined ? '' : ' AND token=?'}`)
70
+ .run(value.state, value.token ?? null, JSON.stringify(value), value.id, expected, ...(token === undefined ? [] : [token])).changes === 1;
71
+ }
72
+ close() { this.#db.close(); }
73
+ }
74
+ //# sourceMappingURL=preparation-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preparation-store.js","sourceRoot":"","sources":["../src/preparation-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import { PreparationStore, type PreparationRecord } from './preparation-store.js';
3
+ export declare class PreparationRuntime {
4
+ #private;
5
+ private readonly ctx;
6
+ readonly store: PreparationStore;
7
+ constructor(ctx: Context, store: PreparationStore);
8
+ available(): boolean;
9
+ current(record: PreparationRecord): void;
10
+ tick(): Promise<void>;
11
+ }
12
+ //# sourceMappingURL=preparation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preparation.d.ts","sourceRoot":"","sources":["../src/preparation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAA0B,MAAM,wBAAwB,CAAA;AAOzG,qBAAa,kBAAkB;;IAIjB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAW,QAAQ,CAAC,KAAK,EAAE,gBAAgB;gBAA9C,GAAG,EAAE,OAAO,EAAW,KAAK,EAAE,gBAAgB;IAY3E,SAAS,IAAI,OAAO;IAEpB,OAAO,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAQxC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CA2BtB"}
@@ -0,0 +1,86 @@
1
+ import { PreparationStore } from './preparation-store.js';
2
+ export class PreparationRuntime {
3
+ ctx;
4
+ store;
5
+ #abort = new AbortController();
6
+ #operation;
7
+ #closed = false;
8
+ constructor(ctx, store) {
9
+ this.ctx = ctx;
10
+ this.store = store;
11
+ ctx.effect(() => {
12
+ const timer = setInterval(() => { void this.tick().catch(() => { }); }, 500);
13
+ timer.unref?.();
14
+ return async () => {
15
+ this.#closed = true;
16
+ clearInterval(timer);
17
+ this.#abort.abort();
18
+ // The Automation runner owns cancellation and joins its Agent before returning.
19
+ await this.#operation?.catch(() => { });
20
+ this.store.close();
21
+ };
22
+ }, 'assistant-proactive.preparations');
23
+ }
24
+ available() { const ports = this.#ports(); return typeof ports.automation?.runPreparation === 'function' && typeof ports.goals?.assertPreparationCurrent === 'function'; }
25
+ #ports() { return { automation: this.ctx.get('assistantAutomations', false), goals: this.ctx.get('assistantGoals', false) }; }
26
+ current(record) {
27
+ if (this.#closed || this.#abort.signal.aborted)
28
+ throw new Error('assistant-proactive: preparation disposed');
29
+ const stored = this.store.get(record.id);
30
+ if (stored?.state !== 'running' || stored.token !== record.token || Date.now() >= Math.min(record.decision.expiresAt, record.deadlineAt))
31
+ throw new Error('assistant-proactive: preparation authority ended');
32
+ const goals = this.#ports().goals;
33
+ if (typeof goals?.assertPreparationCurrent !== 'function')
34
+ throw new Error('assistant-proactive: preparation goal service unavailable');
35
+ goals.assertPreparationCurrent(record.decision);
36
+ }
37
+ tick() {
38
+ if (this.#closed || !this.available())
39
+ return Promise.resolve();
40
+ if (this.#operation)
41
+ return this.#operation;
42
+ const operation = this.#run();
43
+ this.#operation = operation;
44
+ void operation.finally(() => { if (this.#operation === operation)
45
+ this.#operation = undefined; }).catch(() => { });
46
+ return operation;
47
+ }
48
+ async #run() {
49
+ const pending = this.store.pending()[0];
50
+ if (!pending)
51
+ return;
52
+ const record = this.store.claim(pending.id);
53
+ if (!record)
54
+ return;
55
+ try {
56
+ this.current(record);
57
+ }
58
+ catch {
59
+ this.store.finish(record, 'cancelled', undefined, 'authority-unavailable');
60
+ return;
61
+ }
62
+ const auto = this.#ports().automation;
63
+ const decision = record.decision;
64
+ try {
65
+ const result = await auto.runPreparation({ id: record.id, goalId: decision.goalId, scope: decision.scope, sessionId: decision.sessionId, ownerRouteId: decision.ownerRouteId,
66
+ objective: decision.objective, ...record.settings, expiresAt: Math.min(decision.expiresAt, record.deadlineAt) }, this.#abort.signal, () => this.current(record));
67
+ try {
68
+ this.current(record);
69
+ }
70
+ catch {
71
+ this.store.finish(record, 'cancelled', undefined, 'authority-ended');
72
+ return;
73
+ }
74
+ if (result.outcome === 'succeeded' && result.quiescent === true && result.output.trim().length > 0 && Buffer.byteLength(result.output) <= 262_144) {
75
+ this.store.finish(record, 'draft', result, 'unverified-draft');
76
+ }
77
+ else {
78
+ this.store.finish(record, result.quiescent === true ? 'failed' : 'unknown', Buffer.byteLength(result.output) <= 262_144 ? result : undefined, 'generation-not-completed');
79
+ }
80
+ }
81
+ catch {
82
+ this.store.finish(record, 'unknown', undefined, 'generation-unconfirmed');
83
+ }
84
+ }
85
+ }
86
+ //# sourceMappingURL=preparation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preparation.js","sourceRoot":"","sources":["../src/preparation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { OpportunityDecision, OpportunityProfile } from './types.js';
2
+ /** Plain text only. The event supplies identifiers, never new instructions or authority. */
3
+ export declare function reminderText(decision: Readonly<OpportunityDecision>, profile: Readonly<OpportunityProfile>): string;
4
+ /** A queued reminder expires at the next quiet interval; it cannot arrive during a later silent period. */
5
+ export declare function reminderExpiresAt(decision: Readonly<OpportunityDecision>, profile: Readonly<OpportunityProfile>): number;
6
+ //# sourceMappingURL=reminder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reminder.d.ts","sourceRoot":"","sources":["../src/reminder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEzE,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,kBAAkB,CAAC,GAAG,MAAM,CAGnH;AAED,2GAA2G;AAC3G,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,kBAAkB,CAAC,GAAG,MAAM,CAexH"}
@@ -0,0 +1,27 @@
1
+ /** Plain text only. The event supplies identifiers, never new instructions or authority. */
2
+ export function reminderText(decision, profile) {
3
+ const objective = decision.objective.length > 500 ? `${decision.objective.slice(0, 500)}…` : decision.objective;
4
+ return `主动提醒:目标有新的相关事件\n\n目标:${objective}\n来源:${decision.sourceId}\n事件:${decision.eventId}\n\n配置估值:预期收益 ${profile.expectedBenefit},成功系数 ${profile.successPpm / 10_000}%,执行成本 ${profile.executionCost},打扰成本 ${profile.interruptionCost},潜在损失 ${profile.possibleLoss};净收益分值 ${decision.utility}。这些是配置估计,未经实际效果验证。\n\n目标仍在等待。本次仅提醒,未执行目标任务。可查看 proactive_status,并用 proactive_feedback 接受或拒绝这条机会。\n机会:${decision.id}`;
5
+ }
6
+ /** A queued reminder expires at the next quiet interval; it cannot arrive during a later silent period. */
7
+ export function reminderExpiresAt(decision, profile) {
8
+ const quiet = profile.quietHours;
9
+ if (!quiet)
10
+ return decision.expiresAt;
11
+ const formatter = new Intl.DateTimeFormat('en-US', { timeZone: quiet.timezone, hour: '2-digit', minute: '2-digit', hourCycle: 'h23' });
12
+ const isQuiet = (at) => {
13
+ const parts = formatter.formatToParts(new Date(at));
14
+ const minute = Number(parts.find(part => part.type === 'hour')?.value) * 60 + Number(parts.find(part => part.type === 'minute')?.value);
15
+ return quiet.startMinute < quiet.endMinute ? minute >= quiet.startMinute && minute < quiet.endMinute : minute >= quiet.startMinute || minute < quiet.endMinute;
16
+ };
17
+ const start = decision.updatedAt;
18
+ if (isQuiet(start))
19
+ return start;
20
+ // Minute boundaries match the configured granularity; include the extra DST hour.
21
+ const bound = Math.min(decision.expiresAt, start + 26 * 3_600_000);
22
+ for (let at = Math.floor(start / 60_000) * 60_000 + 60_000; at < bound; at += 60_000)
23
+ if (isQuiet(at))
24
+ return at;
25
+ return bound;
26
+ }
27
+ //# sourceMappingURL=reminder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reminder.js","sourceRoot":"","sources":["../src/reminder.ts"],"names":[],"mappings":"AAEA,4FAA4F;AAC5F,MAAM,UAAU,YAAY,CAAC,QAAuC,EAAE,OAAqC;IACzG,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAA;IAC/G,OAAO,wBAAwB,SAAS,QAAQ,QAAQ,CAAC,QAAQ,QAAQ,QAAQ,CAAC,OAAO,iBAAiB,OAAO,CAAC,eAAe,SAAS,OAAO,CAAC,UAAU,GAAG,MAAM,UAAU,OAAO,CAAC,aAAa,SAAS,OAAO,CAAC,gBAAgB,SAAS,OAAO,CAAC,YAAY,UAAU,QAAQ,CAAC,OAAO,wGAAwG,QAAQ,CAAC,EAAE,EAAE,CAAA;AACnZ,CAAC;AAED,2GAA2G;AAC3G,MAAM,UAAU,iBAAiB,CAAC,QAAuC,EAAE,OAAqC;IAC9G,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAA;IAChC,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC,SAAS,CAAA;IACrC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAA;IACtI,MAAM,OAAO,GAAG,CAAC,EAAU,EAAW,EAAE;QACtC,MAAM,KAAK,GAAG,SAAS,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;QACnD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAA;QACvI,OAAO,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,MAAM,GAAG,KAAK,CAAC,SAAS,CAAA;IAChK,CAAC,CAAA;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAA;IAChC,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAChC,kFAAkF;IAClF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,EAAE,KAAK,GAAG,EAAE,GAAG,SAAS,CAAC,CAAA;IAClE,KAAK,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE,IAAI,MAAM;QAAE,IAAI,OAAO,CAAC,EAAE,CAAC;YAAE,OAAO,EAAE,CAAA;IAChH,OAAO,KAAK,CAAA;AACd,CAAC"}
package/lib/types.d.ts ADDED
@@ -0,0 +1,95 @@
1
+ export interface OpportunityScope {
2
+ principalId: string;
3
+ principalRecordId: string;
4
+ principalVersion: number;
5
+ workspace: string;
6
+ preset: string;
7
+ }
8
+ /** Operator estimates in utility units; neither probabilities nor money are independently verified. */
9
+ export interface PreparationSettings {
10
+ provider: string;
11
+ model: string;
12
+ budgetId: string;
13
+ maxOutputTokens: number;
14
+ timeoutMs: number;
15
+ }
16
+ export interface OpportunityProfile {
17
+ /** Explicit opt-in to paid, tool-free generation; omitted prepare keeps metadata-only behavior. */
18
+ preparation?: PreparationSettings;
19
+ id: string;
20
+ mode: 'prepare' | 'remind' | 'execute';
21
+ expectedBenefit: number;
22
+ successPpm: number;
23
+ executionCost: number;
24
+ interruptionCost: number;
25
+ possibleLoss: number;
26
+ minimumUtility: number;
27
+ mergeWindowMs: number;
28
+ cooldownMs: number;
29
+ rejectionCooldownMs: number;
30
+ quietHours?: {
31
+ timezone: string;
32
+ startMinute: number;
33
+ endMinute: number;
34
+ };
35
+ maxDecisionsPerGoal: number;
36
+ maxExecutionsPerGoal: number;
37
+ maxRemindersPerGoal: number;
38
+ }
39
+ /** Supplied by the live Goals service from an already owner-authorized wait; never by an event body. */
40
+ export interface OpportunityInput {
41
+ waitId: string;
42
+ profileId: string;
43
+ scope: OpportunityScope;
44
+ goalId: string;
45
+ sessionId: string;
46
+ definitionDigest: string;
47
+ objective: string;
48
+ nativeGoalId: string;
49
+ nativeRevision: number;
50
+ ownerRouteId: string;
51
+ sourceDigest: string;
52
+ sourceId: string;
53
+ event: {
54
+ id: string;
55
+ sequence: number;
56
+ digest: string;
57
+ occurredAt: number;
58
+ };
59
+ expiresAt: number;
60
+ }
61
+ export type OpportunityReason = 'cancelled' | 'coalescing' | 'quiet-hours' | 'cooldown' | 'rejected-cooldown' | 'below-threshold' | 'budget' | 'expired' | 'prepared' | 'reminder' | 'execution';
62
+ export interface OpportunityDecision {
63
+ id: string;
64
+ waitId: string;
65
+ profileId: string;
66
+ scope: OpportunityScope;
67
+ goalId: string;
68
+ sessionId: string;
69
+ ownerRouteId: string;
70
+ sourceId: string;
71
+ eventId: string;
72
+ eventSequence: number;
73
+ eventDigest: string;
74
+ sourceDigest: string;
75
+ objective: string;
76
+ definitionDigest: string;
77
+ nativeGoalId: string;
78
+ nativeRevision: number;
79
+ mode: 'prepare' | 'remind' | 'execute' | 'suppress';
80
+ state: 'pending' | 'decided' | 'closed';
81
+ reason: OpportunityReason;
82
+ utility: number;
83
+ firstObservedAt: number;
84
+ updatedAt: number;
85
+ eligibleAt: number;
86
+ expiresAt: number;
87
+ observations: number;
88
+ feedback?: 'accepted' | 'rejected';
89
+ }
90
+ export interface OpportunityEvaluation {
91
+ /** consume advances this wait's source cursor; execute still goes through the original GoalWake authority. */
92
+ disposition: 'defer' | 'consume' | 'execute';
93
+ decision: Readonly<OpportunityDecision>;
94
+ }
95
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/lib/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export declare const version = "0.1.30";
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,WAAW,CAAA"}
package/lib/version.js ADDED
@@ -0,0 +1,2 @@
1
+ export const version = '0.1.30';
2
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAA"}