@semiont/jobs 0.5.5 → 0.5.6

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/README.md CHANGED
@@ -10,7 +10,7 @@ Job queue, worker infrastructure, and annotation workers for [Semiont](https://g
10
10
 
11
11
  ## Architecture Context
12
12
 
13
- Workers run in a separate separate process and connect to the Knowledge System (KS) over HTTP/SSE using `WorkerStateUnit` from `@semiont/api-client`. Workers receive job assignments via SSE push, claim jobs atomically, and emit domain events back to the KS via HTTP. The KS ingests these events onto its EventBus for SSE delivery to the frontend.
13
+ Workers run in a separate process and connect to the Knowledge System (KS) over HTTP/SSE using a `SemiontSession` (from `@semiont/sdk`) driven by a `JobClaimAdapter`. Workers receive job assignments via an SSE `job:queued` subscription, claim jobs atomically, and emit domain events back to the KS via `session.client.transport.emit(...)`. The KS ingests these events onto its EventBus for SSE delivery to the frontend.
14
14
 
15
15
  ## Installation
16
16
 
@@ -19,20 +19,24 @@ npm install @semiont/jobs
19
19
  ```
20
20
 
21
21
  **Dependencies:**
22
- - `@semiont/core` — Core types, EventBus
23
- - `@semiont/api-client` — OpenAPI types
22
+ - `@semiont/core` — Core types, `SemiontProject`, EventBus
23
+ - `@semiont/sdk` — `SemiontSession`, `JobClaimAdapter` (worker process)
24
+ - `@semiont/api-client` — HTTP transport, OpenAPI types
24
25
  - `@semiont/inference` — InferenceClient for AI operations
26
+ - `@semiont/content` — Content storage URI derivation
27
+ - `@semiont/observability` — Spans and job-outcome metrics
25
28
 
26
29
  ## Quick Start
27
30
 
28
31
  ```typescript
29
- import { JobQueue, type PendingJob, type GenerationParams } from '@semiont/jobs';
30
- import { EventBus, userId, resourceId, annotationId } from '@semiont/core';
31
- import { jobId } from '@semiont/api-client';
32
+ import { FsJobQueue, type PendingJob, type GenerationParams } from '@semiont/jobs';
33
+ import { EventBus, userId, resourceId, annotationId, jobId } from '@semiont/core';
34
+ import { SemiontProject } from '@semiont/core/node';
32
35
 
33
- // Initialize
36
+ // Initialize — jobs are stored under project.jobsDir
34
37
  const eventBus = new EventBus();
35
- const jobQueue = new JobQueue({ dataDir: './data' }, logger, eventBus);
38
+ const project = new SemiontProject('/path/to/project');
39
+ const jobQueue = new FsJobQueue(project, logger, eventBus);
36
40
  await jobQueue.initialize();
37
41
 
38
42
  // Create a job
@@ -97,45 +101,30 @@ The `userName`, `userEmail`, and `userDomain` fields are used by workers to buil
97
101
 
98
102
  ## Annotation Workers
99
103
 
100
- Six workers process different annotation types:
104
+ The worker process (`worker-main.ts` `startWorkerProcess` in `worker-process.ts`) claims jobs over the bus via a `JobClaimAdapter` and dispatches by `jobType` to a processor function. There are no per-type worker classes; each job type maps to one `process*Job` function:
101
105
 
102
- | Worker | Job Type | Constructor |
103
- |--------|----------|------------|
104
- | `ReferenceAnnotationWorker` | `reference-annotation` | `(jobQueue, config, inferenceClient, eventBus, contentFetcher, logger)` |
105
- | `GenerationWorker` | `generation` | `(jobQueue, config, inferenceClient, eventBus, logger)` |
106
- | `HighlightAnnotationWorker` | `highlight-annotation` | `(jobQueue, config, inferenceClient, eventBus, contentFetcher, logger)` |
107
- | `AssessmentAnnotationWorker` | `assessment-annotation` | `(jobQueue, config, inferenceClient, eventBus, contentFetcher, logger)` |
108
- | `CommentAnnotationWorker` | `comment-annotation` | `(jobQueue, config, inferenceClient, eventBus, contentFetcher, logger)` |
109
- | `TagAnnotationWorker` | `tag-annotation` | `(jobQueue, config, inferenceClient, eventBus, contentFetcher, logger)` |
106
+ | Job Type | Processor |
107
+ |----------|-----------|
108
+ | `reference-annotation` | `processReferenceJob` |
109
+ | `generation` | `processGenerationJob` |
110
+ | `highlight-annotation` | `processHighlightJob` |
111
+ | `assessment-annotation` | `processAssessmentJob` |
112
+ | `comment-annotation` | `processCommentJob` |
113
+ | `tag-annotation` | `processTagJob` |
110
114
 
111
- Workers emit EventBus commands (`mark:create`, `job:start`, `job:complete`, etc.) the Stower actor in @semiont/make-meaning handles persistence.
115
+ Detection logic lives in the `AnnotationDetection` class (`src/workers/annotation-detection.ts`); generation synthesis in `generateResourceFromTopic()` (`src/workers/generation/resource-generation.ts`). Each processor fetches content via `session.client.browse.resourceContent(resourceId)`.
112
116
 
113
- ## Custom Workers
117
+ Workers emit bus events via `session.client.transport.emit('mark:create' | 'job:start' | 'job:report-progress' | 'job:complete' | 'job:fail', payload)` — the Stower actor in @semiont/make-meaning handles persistence.
114
118
 
115
- ```typescript
116
- import { JobWorker, type AnyJob } from '@semiont/jobs';
117
- import type { Logger } from '@semiont/core';
118
-
119
- class MyWorker extends JobWorker {
120
- constructor(jobQueue: JobQueue, logger: Logger) {
121
- super(jobQueue, 1000, 5000, logger);
122
- // ^^^^ ^^^^
123
- // poll error backoff
124
- }
119
+ ## Adding a Job Type
125
120
 
126
- protected getWorkerName(): string {
127
- return 'MyWorker';
128
- }
121
+ Workers are not subclassed. To add a job type:
129
122
 
130
- protected canProcessJob(job: AnyJob): boolean {
131
- return job.metadata.type === 'generation';
132
- }
123
+ 1. Add the new `JobType` and its params/result/progress types in `src/types.ts`.
124
+ 2. Add a `process*Job` function in `src/processors.ts` that runs the inference and returns the annotations/result.
125
+ 3. Dispatch the new `jobType` to that processor in `handleJobInner()` in `src/worker-process.ts`.
133
126
 
134
- protected async executeJob(job: AnyJob): Promise<any> {
135
- // Your processing logic — return result object
136
- }
137
- }
138
- ```
127
+ Processors are transport-agnostic: they take content, an `InferenceClient`, the job params, the user id, the `generator` (W3C SoftwareAgent), and an `onProgress` callback, and return annotations plus a result. The worker process handles claiming, content fetching, and lifecycle event emission.
139
128
 
140
129
  ## Discriminated Unions
141
130
 
@@ -182,7 +171,8 @@ Apache-2.0
182
171
 
183
172
  ## Related Packages
184
173
 
185
- - [`@semiont/core`](../core/) — Domain types, EventBus
186
- - [`@semiont/api-client`](../api-client/) — OpenAPI types
174
+ - [`@semiont/core`](../core/) — Domain types, `SemiontProject`, EventBus
175
+ - [`@semiont/sdk`](../sdk/) — `SemiontSession`, `JobClaimAdapter`
176
+ - [`@semiont/api-client`](../api-client/) — HTTP transport, OpenAPI types
187
177
  - [`@semiont/inference`](../inference/) — AI inference client
188
178
  - [`@semiont/make-meaning`](../make-meaning/) — Actor model, Knowledge Base, service orchestration
package/dist/index.d.ts CHANGED
@@ -415,80 +415,14 @@ declare class FsJobQueue implements JobQueue {
415
415
  }
416
416
 
417
417
  /**
418
- * Job Worker Base Class
419
- *
420
- * Abstract worker that polls the job queue and processes jobs.
421
- * Subclasses implement specific job processing logic.
422
- */
423
-
424
- declare abstract class JobWorker {
425
- private running;
426
- private currentJob;
427
- private pollIntervalMs;
428
- private errorBackoffMs;
429
- protected jobQueue: JobQueue;
430
- protected logger: Logger;
431
- constructor(jobQueue: JobQueue, pollIntervalMs: number | undefined, errorBackoffMs: number | undefined, logger: Logger);
432
- /**
433
- * Start the worker (polls queue in loop)
434
- */
435
- start(): Promise<void>;
436
- /**
437
- * Stop the worker (graceful shutdown)
438
- */
439
- stop(): Promise<void>;
440
- /**
441
- * Poll for next job to process
442
- */
443
- private pollNextJob;
444
- /**
445
- * Process a job (handles state transitions and error handling)
446
- */
447
- private processJob;
448
- /**
449
- * Handle job failure (retry or move to failed)
450
- */
451
- protected handleJobFailure(job: AnyJob, error: any): Promise<void>;
452
- /**
453
- * Update job progress (best-effort, doesn't throw)
454
- */
455
- protected updateJobProgress(job: AnyJob): Promise<void>;
456
- /**
457
- * Sleep utility
458
- */
459
- protected sleep(ms: number): Promise<void>;
460
- /**
461
- * Emit completion event (optional hook for subclasses)
462
- * Override this to emit job-specific completion events (e.g., job.completed)
463
- */
464
- protected emitCompletionEvent(_job: RunningJob<any, any>, _result: any): Promise<void>;
465
- /**
466
- * Get worker name (for logging)
467
- */
468
- protected abstract getWorkerName(): string;
469
- /**
470
- * Check if this worker can process the given job
471
- */
472
- protected abstract canProcessJob(job: AnyJob): boolean;
473
- /**
474
- * Execute the job (job-specific logic)
475
- * This is where the actual work happens
476
- * Return the result object (or void for jobs without results)
477
- * Throw an error to trigger retry logic
478
- */
479
- protected abstract executeJob(job: AnyJob): Promise<any>;
480
- }
481
-
482
- /**
483
- * Job Processors — extracted from JobWorker subclasses
418
+ * Job Processors
484
419
  *
485
420
  * Pure functions that take content + inference client + params,
486
421
  * report progress via callback, and return annotations + results.
487
422
  *
488
423
  * No EventBus, no JobQueue, no side effects except calling inference.
489
- * Two callers:
490
- * 1. In-process JobWorker subclasses (existing path)
491
- * 2. Remote WorkerStateUnit via worker-process.ts (new path)
424
+ * Driven by the remote worker process (worker-process.ts), which claims
425
+ * jobs over SSE and dispatches by jobType to these functions.
492
426
  */
493
427
 
494
428
  type Agent = components['schemas']['Agent'];
@@ -641,5 +575,5 @@ declare function generateResourceFromTopic(topic: string, entityTypes: string[],
641
575
  content: string;
642
576
  }>;
643
577
 
644
- export { AnnotationDetection, FsJobQueue, JobWorker, generateResourceFromTopic, isCancelledJob, isCompleteJob, isFailedJob, isPendingJob, isRunningJob, processAssessmentJob, processCommentJob, processGenerationJob, processHighlightJob, processReferenceJob, processTagJob };
578
+ export { AnnotationDetection, FsJobQueue, generateResourceFromTopic, isCancelledJob, isCompleteJob, isFailedJob, isPendingJob, isRunningJob, processAssessmentJob, processCommentJob, processGenerationJob, processHighlightJob, processReferenceJob, processTagJob };
645
579
  export type { AnyJob, AssessmentDetectionJob, AssessmentDetectionParams, AssessmentDetectionProgress, AssessmentDetectionResult, CancelledJob, CommentDetectionJob, CommentDetectionParams, CommentDetectionProgress, CommentDetectionResult, CompleteJob, ContentFetcher, DetectionJob, DetectionParams, DetectionProgress, DetectionResult, FailedJob, GenerationJob, GenerationParams, GenerationResult, HighlightDetectionJob, HighlightDetectionParams, HighlightDetectionProgress, HighlightDetectionResult, JobMetadata, JobQueryFilters, JobQueue, JobStatus, JobType, OnProgress, PendingJob, ProcessorResult, RunningJob, TagDetectionJob, TagDetectionParams, TagDetectionProgress, TagDetectionResult, YieldProgress };