Add durable candidate funnel
This commit is contained in:
1 parent
5abac31c28
commit
df35648920
20 files changed
+1128
-142
No files matched your search
@@ -31,6 +31,7 @@ import type { ProcessorService } from './processor.js';
|
||||
import type { ResponseCheckerService } from './response-checker.js';
|
||||
import type { RedditPost } from '../reddit/api.js';
|
||||
import type { ConversationAutomationService } from './conversation-automation.js';
|
||||
import type { ProcessedPost, ProcessResult } from './processor.js';
|
||||
|
||||
/** Credentials passed to a factory. They must never be exposed by list/snapshot APIs. */
|
||||
export interface VerifiedAccountSession {
|
||||
@@ -85,8 +86,15 @@ export interface RedditAccountRuntimeLifecycle {
|
||||
stop(): void | Promise<void>;
|
||||
/** Process a post assigned by the shared discovery scheduler. */
|
||||
dispatchPost?(post: RedditPost, signal?: AbortSignal): Promise<void>;
|
||||
preparePost?(post: RedditPost, signal?: AbortSignal): Promise<ProcessResult>;
|
||||
dispatchPreparedPost?(post: ProcessedPost, signal?: AbortSignal): Promise<PreparedDeliveryResult>;
|
||||
}
|
||||
|
||||
export type PreparedDeliveryResult =
|
||||
| { status: 'sent'; conversationId: string }
|
||||
| { status: 'terminal'; reason: string }
|
||||
| { status: 'retryable'; reason: string; retryAt: number };
|
||||
|
||||
export type RedditAccountRuntimeState =
|
||||
| 'created'
|
||||
| 'starting'
|
||||
@@ -185,6 +193,26 @@ export class RedditAccountRuntime {
|
||||
return this.resources.rateLimiter.getTimers().nextMessageAvailableAt === null;
|
||||
}
|
||||
|
||||
async canScan(): Promise<boolean> {
|
||||
if (this.state !== 'running') return false;
|
||||
return this.resources.accountAuth.isFullyAuthenticated()
|
||||
|| await this.resources.accountAuth.ensureFullyAuthenticated();
|
||||
}
|
||||
|
||||
preparePost(post: RedditPost, signal?: AbortSignal): Promise<ProcessResult> {
|
||||
if (this.state !== 'running' || !this.lifecycle.preparePost) {
|
||||
throw new Error(`Runtime ${this.session.redditUsername} cannot prepare candidates`);
|
||||
}
|
||||
return this.lifecycle.preparePost(post, signal);
|
||||
}
|
||||
|
||||
dispatchPreparedPost(post: ProcessedPost, signal?: AbortSignal): Promise<PreparedDeliveryResult> {
|
||||
if (this.state !== 'running' || !this.lifecycle.dispatchPreparedPost) {
|
||||
throw new Error(`Runtime ${this.session.redditUsername} cannot dispatch prepared candidates`);
|
||||
}
|
||||
return this.lifecycle.dispatchPreparedPost(post, signal);
|
||||
}
|
||||
|
||||
dispatchPost(post: RedditPost, signal?: AbortSignal): Promise<void> {
|
||||
if (this.state !== 'running') {
|
||||
throw new Error(`Cannot assign a post to ${this.session.redditUsername}: runtime is not running`);
|
||||
|
||||
Reference in new issue
Block a user