feat: SignalSource abstraction — generalize signal ingestion beyond Todoist (#78)
- Add Signal + SignalSource interfaces to packages/shared-types - TipCandidate.features widened to Record<string,number|boolean> to match Signal - TodoistSignalSource: encapsulates fetch, cache, 401 handling, bus events, and act() - SignalAggregator: parallel fan-out across sources with per-source failure isolation - Recommender refactored to consume Signal[] via aggregator; source action dispatch via aggregator.act() - ADR-0009: signal normalization strategy Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
18
packages/shared-types/src/http/signal.ts
Normal file
18
packages/shared-types/src/http/signal.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/** A normalized signal from any connected source */
|
||||
export interface Signal {
|
||||
id: string;
|
||||
source: string; // e.g. 'todoist', 'google-calendar', 'manual'
|
||||
kind: 'task' | 'event' | 'habit' | 'insight';
|
||||
content: string;
|
||||
metadata: Record<string, unknown>; // source-specific raw fields
|
||||
features: Record<string, number | boolean>; // bandit-ready numeric/boolean features
|
||||
timestamp: string; // ISO 8601
|
||||
}
|
||||
|
||||
/** A pluggable data source that produces normalized signals */
|
||||
export interface SignalSource {
|
||||
readonly id: string;
|
||||
fetchSignals(userId: string): Promise<Signal[]>;
|
||||
/** Optional: perform an action on the originating system (e.g. mark task done) */
|
||||
act?(userId: string, signalId: string, action: string): Promise<void>;
|
||||
}
|
||||
@@ -18,13 +18,11 @@ export interface Tip {
|
||||
/**
|
||||
* A scored tip candidate flowing through the bandit pipeline.
|
||||
* Extends Tip with features needed for scoring.
|
||||
* features is a flexible map so new signal sources can contribute without
|
||||
* schema changes — the bandit serialises them as-is.
|
||||
*/
|
||||
export interface TipCandidate extends Tip {
|
||||
features: {
|
||||
is_overdue: boolean;
|
||||
task_age_days: number;
|
||||
priority: number;
|
||||
};
|
||||
features: Record<string, number | boolean>;
|
||||
}
|
||||
|
||||
/** POST /recommend response */
|
||||
|
||||
@@ -2,3 +2,4 @@ export * from './http/tip.js';
|
||||
export * from './http/auth.js';
|
||||
export * from './http/integrations.js';
|
||||
export * from './http/user.js';
|
||||
export * from './http/signal.js';
|
||||
|
||||
Reference in New Issue
Block a user