@semiont/make-meaning 0.2.30-build.61 → 0.2.30-build.63

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/resource-context.ts","../src/annotation-context.ts","../src/graph-context.ts","../src/annotation-detection.ts","../src/jobs/workers/comment-detection-worker.ts","../src/jobs/workers/highlight-detection-worker.ts","../src/jobs/workers/assessment-detection-worker.ts","../src/jobs/workers/tag-detection-worker.ts","../src/jobs/workers/reference-detection-worker.ts","../src/jobs/workers/generation-worker.ts","../src/index.ts"],"sourcesContent":["/**\n * Resource Context\n *\n * Assembles resource context from view storage and content store\n * Does NOT touch the graph - graph queries go through GraphContext\n */\n\nimport { FilesystemViewStorage } from '@semiont/event-sourcing';\nimport { FilesystemRepresentationStore } from '@semiont/content';\nimport { getPrimaryRepresentation, decodeRepresentation } from '@semiont/api-client';\nimport type { components } from '@semiont/api-client';\nimport type { EnvironmentConfig, ResourceId } from '@semiont/core';\n\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\n\nexport interface ListResourcesFilters {\n search?: string;\n archived?: boolean;\n}\n\nexport class ResourceContext {\n /**\n * Get resource metadata from view storage\n */\n static async getResourceMetadata(resourceId: ResourceId, config: EnvironmentConfig): Promise<ResourceDescriptor | null> {\n const basePath = config.services.filesystem!.path;\n const projectRoot = config._metadata?.projectRoot;\n\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n\n const view = await viewStorage.get(resourceId);\n if (!view) {\n return null;\n }\n\n return view.resource;\n }\n\n /**\n * List all resources by scanning view storage\n */\n static async listResources(filters: ListResourcesFilters | undefined, config: EnvironmentConfig): Promise<ResourceDescriptor[]> {\n const basePath = config.services.filesystem!.path;\n const projectRoot = config._metadata?.projectRoot;\n\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n\n const allViews = await viewStorage.getAll();\n const resources: ResourceDescriptor[] = [];\n\n for (const view of allViews) {\n const doc = view.resource;\n\n // Apply filters\n if (filters?.archived !== undefined && doc.archived !== filters.archived) {\n continue;\n }\n\n if (filters?.search) {\n const searchLower = filters.search.toLowerCase();\n if (!doc.name.toLowerCase().includes(searchLower)) {\n continue;\n }\n }\n\n resources.push(doc);\n }\n\n // Sort by creation date (newest first)\n resources.sort((a, b) => {\n const aTime = a.dateCreated ? new Date(a.dateCreated).getTime() : 0;\n const bTime = b.dateCreated ? new Date(b.dateCreated).getTime() : 0;\n return bTime - aTime;\n });\n\n return resources;\n }\n\n /**\n * Add content previews to resources (for search results)\n * Retrieves and decodes the first 200 characters of each resource's primary representation\n */\n static async addContentPreviews(\n resources: ResourceDescriptor[],\n config: EnvironmentConfig\n ): Promise<Array<ResourceDescriptor & { content: string }>> {\n const basePath = config.services.filesystem!.path;\n const projectRoot = config._metadata?.projectRoot;\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n\n return await Promise.all(\n resources.map(async (doc) => {\n try {\n const primaryRep = getPrimaryRepresentation(doc);\n if (primaryRep?.checksum && primaryRep?.mediaType) {\n const contentBuffer = await repStore.retrieve(primaryRep.checksum, primaryRep.mediaType);\n const contentPreview = decodeRepresentation(contentBuffer, primaryRep.mediaType).slice(0, 200);\n return { ...doc, content: contentPreview };\n }\n return { ...doc, content: '' };\n } catch {\n return { ...doc, content: '' };\n }\n })\n );\n }\n}\n","/**\n * Annotation Context\n *\n * Assembles annotation context from view storage and content store.\n * Provides methods for:\n * - Getting resource annotations\n * - Building LLM context for annotations\n * - Extracting annotation text context\n * - Generating AI summaries\n */\n\nimport { generateResourceSummary, generateText } from '@semiont/inference';\nimport {\n getBodySource,\n getTargetSource,\n getTargetSelector,\n getResourceEntityTypes,\n getTextPositionSelector,\n getPrimaryRepresentation,\n decodeRepresentation,\n} from '@semiont/api-client';\nimport type { components, AnnotationUri, GenerationContext } from '@semiont/api-client';\nimport { FilesystemRepresentationStore } from '@semiont/content';\nimport { FilesystemViewStorage } from '@semiont/event-sourcing';\nimport type {\n EnvironmentConfig,\n ResourceId,\n ResourceAnnotations,\n AnnotationId,\n AnnotationCategory,\n} from '@semiont/core';\nimport { resourceId as createResourceId, uriToResourceId } from '@semiont/core';\nimport { getEntityTypes } from '@semiont/ontology';\nimport { ResourceContext } from './resource-context';\n\ntype AnnotationLLMContextResponse = components['schemas']['AnnotationLLMContextResponse'];\ntype TextPositionSelector = components['schemas']['TextPositionSelector'];\ntype TextQuoteSelector = components['schemas']['TextQuoteSelector'];\ntype Annotation = components['schemas']['Annotation'];\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\ntype AnnotationContextResponse = components['schemas']['AnnotationContextResponse'];\ntype ContextualSummaryResponse = components['schemas']['ContextualSummaryResponse'];\n\nexport interface BuildContextOptions {\n includeSourceContext?: boolean;\n includeTargetContext?: boolean;\n contextWindow?: number;\n}\n\ninterface AnnotationTextContext {\n before: string;\n selected: string;\n after: string;\n}\n\nexport class AnnotationContext {\n /**\n * Build LLM context for an annotation\n *\n * @param annotationUri - Full annotation URI (e.g., http://localhost:4000/annotations/abc123)\n * @param resourceId - Source resource ID\n * @param config - Application configuration\n * @param options - Context building options\n * @returns Rich context for LLM processing\n * @throws Error if annotation or resource not found\n */\n static async buildLLMContext(\n annotationUri: AnnotationUri,\n resourceId: ResourceId,\n config: EnvironmentConfig,\n options: BuildContextOptions = {}\n ): Promise<AnnotationLLMContextResponse> {\n const {\n includeSourceContext = true,\n includeTargetContext = true,\n contextWindow = 1000\n } = options;\n\n // Validate contextWindow range\n if (contextWindow < 100 || contextWindow > 5000) {\n throw new Error('contextWindow must be between 100 and 5000');\n }\n\n console.log(`[AnnotationContext] buildLLMContext called with annotationUri=${annotationUri}, resourceId=${resourceId}`);\n\n const basePath = config.services.filesystem!.path;\n console.log(`[AnnotationContext] basePath=${basePath}`);\n\n const projectRoot = config._metadata?.projectRoot;\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n\n // Get source resource view\n console.log(`[AnnotationContext] Getting view for resourceId=${resourceId}`);\n let sourceView;\n try {\n sourceView = await viewStorage.get(resourceId);\n console.log(`[AnnotationContext] Got view:`, !!sourceView);\n\n if (!sourceView) {\n throw new Error('Source resource not found');\n }\n } catch (error) {\n console.error(`[AnnotationContext] Error getting view:`, error);\n throw error;\n }\n\n console.log(`[AnnotationContext] Looking for annotation ${annotationUri} in resource ${resourceId}`);\n console.log(`[AnnotationContext] View has ${sourceView.annotations.annotations.length} annotations`);\n console.log(`[AnnotationContext] First 5 annotation IDs:`, sourceView.annotations.annotations.slice(0, 5).map((a: Annotation) => a.id));\n\n // Find the annotation in the view (annotations have full URIs as their id)\n const annotation = sourceView.annotations.annotations.find((a: Annotation) => a.id === annotationUri);\n console.log(`[AnnotationContext] Found annotation:`, !!annotation);\n\n if (!annotation) {\n throw new Error('Annotation not found in view');\n }\n\n const targetSource = getTargetSource(annotation.target);\n // Extract resource ID from the target source URI (format: http://host/resources/{id})\n const targetResourceId = targetSource.split('/').pop();\n console.log(`[AnnotationContext] Target source: ${targetSource}, Expected resource ID: ${resourceId}, Extracted ID: ${targetResourceId}`);\n\n if (targetResourceId !== resourceId) {\n throw new Error(`Annotation target resource ID (${targetResourceId}) does not match expected resource ID (${resourceId})`);\n }\n\n const sourceDoc = sourceView.resource;\n\n // Get target resource if annotation is a reference (has resolved body source)\n const bodySource = getBodySource(annotation.body);\n\n // Extract target document from body source URI if present\n let targetDoc = null;\n if (bodySource) {\n // Inline extraction: \"http://localhost:4000/resources/abc123\" → \"abc123\"\n const parts = (bodySource as string).split('/');\n const lastPart = parts[parts.length - 1];\n if (!lastPart) {\n throw new Error(`Invalid body source URI: ${bodySource}`);\n }\n const targetResourceId = createResourceId(lastPart);\n const targetView = await viewStorage.get(targetResourceId);\n targetDoc = targetView?.resource || null;\n }\n\n // Build source context if requested\n let sourceContext;\n if (includeSourceContext) {\n const primaryRep = getPrimaryRepresentation(sourceDoc);\n if (!primaryRep?.checksum || !primaryRep?.mediaType) {\n throw new Error('Source content not found');\n }\n const sourceContent = await repStore.retrieve(primaryRep.checksum, primaryRep.mediaType);\n const contentStr = decodeRepresentation(sourceContent, primaryRep.mediaType);\n\n const targetSelectorRaw = getTargetSelector(annotation.target);\n\n // Handle array of selectors - take the first one\n const targetSelector = Array.isArray(targetSelectorRaw) ? targetSelectorRaw[0] : targetSelectorRaw;\n\n console.log(`[AnnotationContext] Target selector type:`, targetSelector?.type);\n\n if (!targetSelector) {\n console.warn(`[AnnotationContext] No target selector found`);\n } else if (targetSelector.type === 'TextPositionSelector') {\n // TypeScript now knows this is TextPositionSelector with required start/end\n const selector = targetSelector as TextPositionSelector;\n const start = selector.start;\n const end = selector.end;\n\n const before = contentStr.slice(Math.max(0, start - contextWindow), start);\n const selected = contentStr.slice(start, end);\n const after = contentStr.slice(end, Math.min(contentStr.length, end + contextWindow));\n\n sourceContext = { before, selected, after };\n console.log(`[AnnotationContext] Built source context using TextPositionSelector (${start}-${end})`);\n } else if (targetSelector.type === 'TextQuoteSelector') {\n // TypeScript now knows this is TextQuoteSelector with required exact\n const selector = targetSelector as TextQuoteSelector;\n const exact = selector.exact;\n const index = contentStr.indexOf(exact);\n\n if (index !== -1) {\n const start = index;\n const end = index + exact.length;\n\n const before = contentStr.slice(Math.max(0, start - contextWindow), start);\n const selected = exact;\n const after = contentStr.slice(end, Math.min(contentStr.length, end + contextWindow));\n\n sourceContext = { before, selected, after };\n console.log(`[AnnotationContext] Built source context using TextQuoteSelector (found at ${index})`);\n } else {\n console.warn(`[AnnotationContext] TextQuoteSelector exact text not found in content: \"${exact.substring(0, 50)}...\"`);\n }\n } else {\n console.warn(`[AnnotationContext] Unknown selector type: ${(targetSelector as any).type}`);\n }\n }\n\n // Build target context if requested and available\n let targetContext;\n if (includeTargetContext && targetDoc) {\n const targetRep = getPrimaryRepresentation(targetDoc);\n if (targetRep?.checksum && targetRep?.mediaType) {\n const targetContent = await repStore.retrieve(targetRep.checksum, targetRep.mediaType);\n const contentStr = decodeRepresentation(targetContent, targetRep.mediaType);\n\n targetContext = {\n content: contentStr.slice(0, contextWindow * 2),\n summary: await generateResourceSummary(targetDoc.name, contentStr, getResourceEntityTypes(targetDoc), config),\n };\n }\n }\n\n // TODO: Generate suggested resolution using AI\n const suggestedResolution = undefined;\n\n // Build GenerationContext structure\n const generationContext: GenerationContext | undefined = sourceContext ? {\n sourceContext: {\n before: sourceContext.before || '',\n selected: sourceContext.selected,\n after: sourceContext.after || '',\n },\n metadata: {\n resourceType: 'document',\n language: sourceDoc.language as string | undefined,\n entityTypes: getEntityTypes(annotation),\n },\n } : undefined;\n\n const response: AnnotationLLMContextResponse = {\n annotation,\n sourceResource: sourceDoc,\n targetResource: targetDoc,\n ...(generationContext ? { context: generationContext } : {}),\n ...(sourceContext ? { sourceContext } : {}), // Keep for backward compatibility\n ...(targetContext ? { targetContext } : {}),\n ...(suggestedResolution ? { suggestedResolution } : {}),\n };\n\n return response;\n }\n\n /**\n * Get resource annotations from view storage (fast path)\n * Throws if view missing\n */\n static async getResourceAnnotations(resourceId: ResourceId, config: EnvironmentConfig): Promise<ResourceAnnotations> {\n if (!config.services?.filesystem?.path) {\n throw new Error('Filesystem path not found in configuration');\n }\n const basePath = config.services.filesystem.path;\n const projectRoot = config._metadata?.projectRoot;\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n const view = await viewStorage.get(resourceId);\n\n if (!view) {\n throw new Error(`Resource ${resourceId} not found in view storage`);\n }\n\n return view.annotations;\n }\n\n /**\n * Get all annotations\n * @returns Array of all annotation objects\n */\n static async getAllAnnotations(resourceId: ResourceId, config: EnvironmentConfig): Promise<Annotation[]> {\n const annotations = await this.getResourceAnnotations(resourceId, config);\n\n // Enrich resolved references with document names\n // NOTE: Future optimization - make this optional via query param if performance becomes an issue\n return await this.enrichResolvedReferences(annotations.annotations, config);\n }\n\n /**\n * Enrich reference annotations with resolved document names\n * Adds _resolvedDocumentName property to annotations that link to documents\n * @private\n */\n private static async enrichResolvedReferences(annotations: Annotation[], config: EnvironmentConfig): Promise<Annotation[]> {\n if (!config.services?.filesystem?.path) {\n return annotations;\n }\n\n // Extract unique resolved document URIs from reference annotations\n const resolvedUris = new Set<string>();\n for (const ann of annotations) {\n if (ann.motivation === 'linking' && ann.body) {\n const body = Array.isArray(ann.body) ? ann.body : [ann.body];\n for (const item of body) {\n if (item.purpose === 'linking' && item.source) {\n resolvedUris.add(item.source);\n }\n }\n }\n }\n\n if (resolvedUris.size === 0) {\n return annotations;\n }\n\n // Batch fetch all resolved documents in parallel\n const basePath = config.services.filesystem.path;\n const projectRoot = config._metadata?.projectRoot;\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n\n const metadataPromises = Array.from(resolvedUris).map(async (uri) => {\n const docId = uri.split('/resources/')[1];\n if (!docId) return null;\n\n try {\n const view = await viewStorage.get(docId as ResourceId);\n if (view?.resource?.name) {\n return {\n uri,\n metadata: {\n name: view.resource.name,\n mediaType: view.resource.mediaType as string | undefined\n }\n };\n }\n } catch (e) {\n // Document might not exist, skip\n }\n return null;\n });\n\n const results = await Promise.all(metadataPromises);\n const uriToMetadata = new Map<string, { name: string; mediaType?: string }>();\n for (const result of results) {\n if (result) {\n uriToMetadata.set(result.uri, result.metadata);\n }\n }\n\n // Add _resolvedDocumentName and _resolvedDocumentMediaType to annotations\n return annotations.map(ann => {\n if (ann.motivation === 'linking' && ann.body) {\n const body = Array.isArray(ann.body) ? ann.body : [ann.body];\n for (const item of body) {\n if (item.purpose === 'linking' && item.source) {\n const metadata = uriToMetadata.get(item.source);\n if (metadata) {\n return {\n ...ann,\n _resolvedDocumentName: metadata.name,\n _resolvedDocumentMediaType: metadata.mediaType\n } as Annotation;\n }\n }\n }\n }\n return ann;\n });\n }\n\n /**\n * Get resource stats (version info)\n * @returns Version and timestamp info for the annotations\n */\n static async getResourceStats(resourceId: ResourceId, config: EnvironmentConfig): Promise<{\n resourceId: ResourceId;\n version: number;\n updatedAt: string;\n }> {\n const annotations = await this.getResourceAnnotations(resourceId, config);\n return {\n resourceId: annotations.resourceId,\n version: annotations.version,\n updatedAt: annotations.updatedAt,\n };\n }\n\n /**\n * Check if resource exists in view storage\n */\n static async resourceExists(resourceId: ResourceId, config: EnvironmentConfig): Promise<boolean> {\n if (!config.services?.filesystem?.path) {\n throw new Error('Filesystem path not found in configuration');\n }\n const basePath = config.services.filesystem.path;\n const projectRoot = config._metadata?.projectRoot;\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n return await viewStorage.exists(resourceId);\n }\n\n /**\n * Get a single annotation by ID\n * O(1) lookup using resource ID to access view storage\n */\n static async getAnnotation(annotationId: AnnotationId, resourceId: ResourceId, config: EnvironmentConfig): Promise<Annotation | null> {\n const annotations = await this.getResourceAnnotations(resourceId, config);\n // Extract short ID from annotation's full URI for comparison\n return annotations.annotations.find((a: Annotation) => {\n const shortId = a.id.split('/').pop();\n return shortId === annotationId;\n }) || null;\n }\n\n /**\n * List annotations with optional filtering\n * @param filters - Optional filters like resourceId and type\n * @throws Error if resourceId not provided (cross-resource queries not supported in view storage)\n */\n static async listAnnotations(filters: { resourceId?: ResourceId; type?: AnnotationCategory } | undefined, config: EnvironmentConfig): Promise<Annotation[]> {\n if (!filters?.resourceId) {\n throw new Error('resourceId is required for annotation listing - cross-resource queries not supported in view storage');\n }\n\n // Use view storage directly\n return await this.getAllAnnotations(filters.resourceId, config);\n }\n\n /**\n * Get annotation context (selected text with surrounding context)\n */\n static async getAnnotationContext(\n annotationId: AnnotationId,\n resourceId: ResourceId,\n contextBefore: number,\n contextAfter: number,\n config: EnvironmentConfig\n ): Promise<AnnotationContextResponse> {\n const basePath = config.services.filesystem!.path;\n const projectRoot = config._metadata?.projectRoot;\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n\n // Get annotation from view storage\n const annotation = await this.getAnnotation(annotationId, resourceId, config);\n if (!annotation) {\n throw new Error('Annotation not found');\n }\n\n // Get resource metadata from view storage\n const resource = await ResourceContext.getResourceMetadata(\n uriToResourceId(getTargetSource(annotation.target)),\n config\n );\n if (!resource) {\n throw new Error('Resource not found');\n }\n\n // Get content from representation store\n const contentStr = await this.getResourceContent(resource, repStore);\n\n // Extract context based on annotation position\n const context = this.extractAnnotationContext(annotation, contentStr, contextBefore, contextAfter);\n\n return {\n annotation: annotation,\n context,\n resource: {\n '@context': resource['@context'],\n '@id': resource['@id'],\n name: resource.name,\n entityTypes: resource.entityTypes,\n representations: resource.representations,\n archived: resource.archived,\n creationMethod: resource.creationMethod,\n wasAttributedTo: resource.wasAttributedTo,\n dateCreated: resource.dateCreated,\n },\n };\n }\n\n /**\n * Generate AI summary of annotation in context\n */\n static async generateAnnotationSummary(\n annotationId: AnnotationId,\n resourceId: ResourceId,\n config: EnvironmentConfig\n ): Promise<ContextualSummaryResponse> {\n const basePath = config.services.filesystem!.path;\n const projectRoot = config._metadata?.projectRoot;\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n\n // Get annotation from view storage\n const annotation = await this.getAnnotation(annotationId, resourceId, config);\n if (!annotation) {\n throw new Error('Annotation not found');\n }\n\n // Get resource from view storage\n const resource = await ResourceContext.getResourceMetadata(\n uriToResourceId(getTargetSource(annotation.target)),\n config\n );\n if (!resource) {\n throw new Error('Resource not found');\n }\n\n // Get content from representation store\n const contentStr = await this.getResourceContent(resource, repStore);\n\n // Extract annotation text with context (fixed 500 chars for summary)\n const contextSize = 500;\n const context = this.extractAnnotationContext(annotation, contentStr, contextSize, contextSize);\n\n // Extract entity types from annotation body\n const annotationEntityTypes = getEntityTypes(annotation);\n\n // Generate summary using LLM\n const summary = await this.generateSummary(resource, context, annotationEntityTypes, config);\n\n return {\n summary,\n relevantFields: {\n resourceId: resource.id,\n resourceName: resource.name,\n entityTypes: annotationEntityTypes,\n },\n context: {\n before: context.before.substring(Math.max(0, context.before.length - 200)), // Last 200 chars\n selected: context.selected,\n after: context.after.substring(0, 200), // First 200 chars\n },\n };\n }\n\n /**\n * Get resource content as string\n */\n private static async getResourceContent(\n resource: ResourceDescriptor,\n repStore: FilesystemRepresentationStore\n ): Promise<string> {\n const primaryRep = getPrimaryRepresentation(resource);\n if (!primaryRep?.checksum || !primaryRep?.mediaType) {\n throw new Error('Resource content not found');\n }\n const content = await repStore.retrieve(primaryRep.checksum, primaryRep.mediaType);\n return decodeRepresentation(content, primaryRep.mediaType);\n }\n\n /**\n * Extract annotation context from resource content\n */\n private static extractAnnotationContext(\n annotation: Annotation,\n contentStr: string,\n contextBefore: number,\n contextAfter: number\n ): AnnotationTextContext {\n const targetSelector = getTargetSelector(annotation.target);\n const posSelector = targetSelector ? getTextPositionSelector(targetSelector) : null;\n if (!posSelector) {\n throw new Error('TextPositionSelector required for context');\n }\n\n const selStart = posSelector.start;\n const selEnd = posSelector.end;\n const start = Math.max(0, selStart - contextBefore);\n const end = Math.min(contentStr.length, selEnd + contextAfter);\n\n return {\n before: contentStr.substring(start, selStart),\n selected: contentStr.substring(selStart, selEnd),\n after: contentStr.substring(selEnd, end),\n };\n }\n\n /**\n * Generate LLM summary of annotation in context\n */\n private static async generateSummary(\n resource: ResourceDescriptor,\n context: AnnotationTextContext,\n entityTypes: string[],\n config: EnvironmentConfig\n ): Promise<string> {\n const summaryPrompt = `Summarize this text in context:\n\nContext before: \"${context.before.substring(Math.max(0, context.before.length - 200))}\"\nSelected exact: \"${context.selected}\"\nContext after: \"${context.after.substring(0, 200)}\"\n\nResource: ${resource.name}\nEntity types: ${entityTypes.join(', ')}`;\n\n return await generateText(summaryPrompt, config, 500, 0.5);\n }\n}\n","/**\n * Graph Context\n *\n * Provides graph database operations for resources and annotations.\n * All methods require graph traversal - must use graph database.\n */\n\nimport { getGraphDatabase } from '@semiont/graph';\nimport { resourceIdToURI } from '@semiont/core';\nimport type {\n ResourceId,\n EnvironmentConfig,\n GraphConnection,\n GraphPath,\n} from '@semiont/core';\nimport type { components } from '@semiont/api-client';\n\ntype Annotation = components['schemas']['Annotation'];\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\n\nexport class GraphContext {\n /**\n * Get all resources referencing this resource (backlinks)\n * Requires graph traversal - must use graph database\n */\n static async getBacklinks(resourceId: ResourceId, config: EnvironmentConfig): Promise<Annotation[]> {\n const graphDb = await getGraphDatabase(config);\n const resourceUri = resourceIdToURI(resourceId, config.services.backend!.publicURL);\n return await graphDb.getResourceReferencedBy(resourceUri);\n }\n\n /**\n * Find shortest path between two resources\n * Requires graph traversal - must use graph database\n */\n static async findPath(\n fromResourceId: ResourceId,\n toResourceId: ResourceId,\n config: EnvironmentConfig,\n maxDepth?: number\n ): Promise<GraphPath[]> {\n const graphDb = await getGraphDatabase(config);\n return await graphDb.findPath(fromResourceId, toResourceId, maxDepth);\n }\n\n /**\n * Get resource connections (graph edges)\n * Requires graph traversal - must use graph database\n */\n static async getResourceConnections(resourceId: ResourceId, config: EnvironmentConfig): Promise<GraphConnection[]> {\n const graphDb = await getGraphDatabase(config);\n return await graphDb.getResourceConnections(resourceId);\n }\n\n /**\n * Search resources by name (cross-resource query)\n * Requires full-text search - must use graph database\n */\n static async searchResources(query: string, config: EnvironmentConfig, limit?: number): Promise<ResourceDescriptor[]> {\n const graphDb = await getGraphDatabase(config);\n return await graphDb.searchResources(query, limit);\n }\n}\n","/**\n * Annotation Detection\n *\n * Orchestrates the full annotation detection pipeline:\n * 1. Fetch resource metadata and content\n * 2. Build AI prompts using MotivationPrompts\n * 3. Call AI inference\n * 4. Parse and validate results using MotivationParsers\n *\n * This is the high-level API for AI-powered annotation detection.\n * Workers and other consumers should use these methods instead of\n * implementing detection logic directly.\n */\n\nimport { ResourceContext } from './resource-context';\nimport { FilesystemRepresentationStore } from '@semiont/content';\nimport { getPrimaryRepresentation, decodeRepresentation } from '@semiont/api-client';\nimport {\n MotivationPrompts,\n MotivationParsers,\n generateText,\n type CommentMatch,\n type HighlightMatch,\n type AssessmentMatch,\n type TagMatch,\n} from '@semiont/inference';\nimport { getTagSchema, getSchemaCategory } from '@semiont/ontology';\nimport type { EnvironmentConfig, ResourceId } from '@semiont/core';\n\nexport class AnnotationDetection {\n /**\n * Detect comments in a resource\n *\n * @param resourceId - The resource to analyze\n * @param config - Environment configuration\n * @param instructions - Optional user instructions for comment generation\n * @param tone - Optional tone guidance (e.g., \"academic\", \"conversational\")\n * @param density - Optional target number of comments per 2000 words\n * @returns Array of validated comment matches\n */\n static async detectComments(\n resourceId: ResourceId,\n config: EnvironmentConfig,\n instructions?: string,\n tone?: string,\n density?: number\n ): Promise<CommentMatch[]> {\n // 1. Fetch resource metadata\n const resource = await ResourceContext.getResourceMetadata(resourceId, config);\n if (!resource) {\n throw new Error(`Resource ${resourceId} not found`);\n }\n\n // 2. Load content from representation store\n const content = await this.loadResourceContent(resourceId, config);\n if (!content) {\n throw new Error(`Could not load content for resource ${resourceId}`);\n }\n\n // 3. Build prompt\n const prompt = MotivationPrompts.buildCommentPrompt(content, instructions, tone, density);\n\n // 4. Call AI inference\n const response = await generateText(\n prompt,\n config,\n 3000, // maxTokens: Higher than highlights/assessments due to comment text\n 0.4 // temperature: Slightly higher to allow creative context\n );\n\n // 5. Parse and validate response\n return MotivationParsers.parseComments(response, content);\n }\n\n /**\n * Detect highlights in a resource\n *\n * @param resourceId - The resource to analyze\n * @param config - Environment configuration\n * @param instructions - Optional user instructions for highlight selection\n * @param density - Optional target number of highlights per 2000 words\n * @returns Array of validated highlight matches\n */\n static async detectHighlights(\n resourceId: ResourceId,\n config: EnvironmentConfig,\n instructions?: string,\n density?: number\n ): Promise<HighlightMatch[]> {\n // 1. Fetch resource metadata\n const resource = await ResourceContext.getResourceMetadata(resourceId, config);\n if (!resource) {\n throw new Error(`Resource ${resourceId} not found`);\n }\n\n // 2. Load content from representation store\n const content = await this.loadResourceContent(resourceId, config);\n if (!content) {\n throw new Error(`Could not load content for resource ${resourceId}`);\n }\n\n // 3. Build prompt\n const prompt = MotivationPrompts.buildHighlightPrompt(content, instructions, density);\n\n // 4. Call AI inference\n const response = await generateText(\n prompt,\n config,\n 2000, // maxTokens: Lower than comments/assessments (no body text)\n 0.3 // temperature: Low for consistent importance judgments\n );\n\n // 5. Parse and validate response\n return MotivationParsers.parseHighlights(response, content);\n }\n\n /**\n * Detect assessments in a resource\n *\n * @param resourceId - The resource to analyze\n * @param config - Environment configuration\n * @param instructions - Optional user instructions for assessment generation\n * @param tone - Optional tone guidance (e.g., \"critical\", \"supportive\")\n * @param density - Optional target number of assessments per 2000 words\n * @returns Array of validated assessment matches\n */\n static async detectAssessments(\n resourceId: ResourceId,\n config: EnvironmentConfig,\n instructions?: string,\n tone?: string,\n density?: number\n ): Promise<AssessmentMatch[]> {\n // 1. Fetch resource metadata\n const resource = await ResourceContext.getResourceMetadata(resourceId, config);\n if (!resource) {\n throw new Error(`Resource ${resourceId} not found`);\n }\n\n // 2. Load content from representation store\n const content = await this.loadResourceContent(resourceId, config);\n if (!content) {\n throw new Error(`Could not load content for resource ${resourceId}`);\n }\n\n // 3. Build prompt\n const prompt = MotivationPrompts.buildAssessmentPrompt(content, instructions, tone, density);\n\n // 4. Call AI inference\n const response = await generateText(\n prompt,\n config,\n 3000, // maxTokens: Higher for assessment text\n 0.3 // temperature: Lower for analytical consistency\n );\n\n // 5. Parse and validate response\n return MotivationParsers.parseAssessments(response, content);\n }\n\n /**\n * Detect tags in a resource for a specific category\n *\n * @param resourceId - The resource to analyze\n * @param config - Environment configuration\n * @param schemaId - The tag schema identifier (e.g., \"irac\", \"imrad\")\n * @param category - The specific category to detect\n * @returns Array of validated tag matches\n */\n static async detectTags(\n resourceId: ResourceId,\n config: EnvironmentConfig,\n schemaId: string,\n category: string\n ): Promise<TagMatch[]> {\n // Validate schema and category\n const schema = getTagSchema(schemaId);\n if (!schema) {\n throw new Error(`Invalid tag schema: ${schemaId}`);\n }\n\n const categoryInfo = getSchemaCategory(schemaId, category);\n if (!categoryInfo) {\n throw new Error(`Invalid category \"${category}\" for schema ${schemaId}`);\n }\n\n // 1. Fetch resource metadata\n const resource = await ResourceContext.getResourceMetadata(resourceId, config);\n if (!resource) {\n throw new Error(`Resource ${resourceId} not found`);\n }\n\n // 2. Load content from representation store (FULL content for structural analysis)\n const content = await this.loadResourceContent(resourceId, config);\n if (!content) {\n throw new Error(`Could not load content for resource ${resourceId}`);\n }\n\n // 3. Build prompt with schema and category information\n const prompt = MotivationPrompts.buildTagPrompt(\n content,\n category,\n schema.name,\n schema.description,\n schema.domain,\n categoryInfo.description,\n categoryInfo.examples\n );\n\n // 4. Call AI inference\n const response = await generateText(\n prompt,\n config,\n 4000, // maxTokens: Higher for full document analysis\n 0.2 // temperature: Lower for structural consistency\n );\n\n // 5. Parse response (without validation)\n const parsedTags = MotivationParsers.parseTags(response);\n\n // 6. Validate offsets and add category\n return MotivationParsers.validateTagOffsets(parsedTags, content, category);\n }\n\n /**\n * Load resource content from representation store\n * Helper method used by all detection methods\n *\n * @param resourceId - The resource ID to load\n * @param config - Environment configuration\n * @returns Resource content as string, or null if not available\n */\n private static async loadResourceContent(\n resourceId: ResourceId,\n config: EnvironmentConfig\n ): Promise<string | null> {\n const resource = await ResourceContext.getResourceMetadata(resourceId, config);\n if (!resource) return null;\n\n const primaryRep = getPrimaryRepresentation(resource);\n if (!primaryRep) return null;\n\n // Only process text content\n const baseMediaType = primaryRep.mediaType?.split(';')[0]?.trim() || '';\n if (baseMediaType !== 'text/plain' && baseMediaType !== 'text/markdown') {\n return null;\n }\n\n if (!primaryRep.checksum || !primaryRep.mediaType) return null;\n\n const basePath = config.services.filesystem!.path;\n const projectRoot = config._metadata?.projectRoot;\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n const contentBuffer = await repStore.retrieve(primaryRep.checksum, primaryRep.mediaType);\n return decodeRepresentation(contentBuffer, primaryRep.mediaType);\n }\n}\n","/**\n * Comment Detection Worker\n *\n * Processes comment-detection jobs: runs AI inference to identify passages\n * that would benefit from explanatory comments and creates comment annotations.\n */\n\nimport { JobWorker } from '@semiont/jobs';\nimport type { Job, CommentDetectionJob, JobQueue } from '@semiont/jobs';\nimport { ResourceContext, AnnotationDetection } from '../..';\nimport { EventStore, generateAnnotationId } from '@semiont/event-sourcing';\nimport { resourceIdToURI } from '@semiont/core';\nimport type { EnvironmentConfig, ResourceId } from '@semiont/core';\nimport { userId } from '@semiont/core';\nimport type { CommentMatch } from '@semiont/inference';\n\nexport class CommentDetectionWorker extends JobWorker {\n private isFirstProgress = true;\n\n constructor(\n jobQueue: JobQueue,\n private config: EnvironmentConfig,\n private eventStore: EventStore\n ) {\n super(jobQueue);\n }\n\n protected getWorkerName(): string {\n return 'CommentDetectionWorker';\n }\n\n protected canProcessJob(job: Job): boolean {\n return job.type === 'comment-detection';\n }\n\n protected async executeJob(job: Job): Promise<void> {\n if (job.type !== 'comment-detection') {\n throw new Error(`Invalid job type: ${job.type}`);\n }\n\n // Reset progress tracking\n this.isFirstProgress = true;\n await this.processCommentDetectionJob(job);\n }\n\n /**\n * Override updateJobProgress to emit events to Event Store\n */\n protected override async updateJobProgress(job: Job): Promise<void> {\n // Call parent to update filesystem\n await super.updateJobProgress(job);\n\n if (job.type !== 'comment-detection') return;\n\n const cdJob = job as CommentDetectionJob;\n if (!cdJob.progress) return;\n\n const baseEvent = {\n resourceId: cdJob.resourceId,\n userId: cdJob.userId,\n version: 1,\n };\n\n // Determine if this is completion (100% and has result)\n const isComplete = cdJob.progress.percentage === 100 && cdJob.result;\n\n if (this.isFirstProgress) {\n // First progress update - emit job.started\n this.isFirstProgress = false;\n await this.eventStore.appendEvent({\n type: 'job.started',\n ...baseEvent,\n payload: {\n jobId: cdJob.id,\n jobType: cdJob.type,\n },\n });\n } else if (isComplete) {\n // Final update - emit job.completed\n await this.eventStore.appendEvent({\n type: 'job.completed',\n ...baseEvent,\n payload: {\n jobId: cdJob.id,\n jobType: cdJob.type,\n result: cdJob.result,\n },\n });\n } else {\n // Intermediate progress - emit job.progress\n await this.eventStore.appendEvent({\n type: 'job.progress',\n ...baseEvent,\n payload: {\n jobId: cdJob.id,\n jobType: cdJob.type,\n progress: cdJob.progress,\n },\n });\n }\n }\n\n protected override async handleJobFailure(job: Job, error: any): Promise<void> {\n // Call parent to handle the failure logic\n await super.handleJobFailure(job, error);\n\n // If job permanently failed, emit job.failed event\n if (job.status === 'failed' && job.type === 'comment-detection') {\n const cdJob = job as CommentDetectionJob;\n\n // Log the full error details to backend logs (already logged by parent)\n // Send generic error message to frontend\n await this.eventStore.appendEvent({\n type: 'job.failed',\n resourceId: cdJob.resourceId,\n userId: cdJob.userId,\n version: 1,\n payload: {\n jobId: cdJob.id,\n jobType: cdJob.type,\n error: 'Comment detection failed. Please try again later.',\n },\n });\n }\n }\n\n private async processCommentDetectionJob(job: CommentDetectionJob): Promise<void> {\n console.log(`[CommentDetectionWorker] Processing comment detection for resource ${job.resourceId} (job: ${job.id})`);\n\n // Fetch resource content\n const resource = await ResourceContext.getResourceMetadata(job.resourceId, this.config);\n\n if (!resource) {\n throw new Error(`Resource ${job.resourceId} not found`);\n }\n\n // Emit job.started and start analyzing\n job.progress = {\n stage: 'analyzing',\n percentage: 10,\n message: 'Loading resource...'\n };\n await this.updateJobProgress(job);\n\n // Update progress\n job.progress = {\n stage: 'analyzing',\n percentage: 30,\n message: 'Analyzing text and generating comments...'\n };\n await this.updateJobProgress(job);\n\n // Use AI to detect passages needing comments\n const comments = await AnnotationDetection.detectComments(\n job.resourceId,\n this.config,\n job.instructions,\n job.tone,\n job.density\n );\n\n console.log(`[CommentDetectionWorker] Found ${comments.length} comments to create`);\n\n // Update progress\n job.progress = {\n stage: 'creating',\n percentage: 60,\n message: `Creating ${comments.length} annotations...`\n };\n await this.updateJobProgress(job);\n\n // Create annotations for each comment\n let created = 0;\n for (const comment of comments) {\n try {\n await this.createCommentAnnotation(job.resourceId, job.userId, comment);\n created++;\n } catch (error) {\n console.error(`[CommentDetectionWorker] Failed to create comment:`, error);\n }\n }\n\n // Complete job\n job.result = {\n commentsFound: comments.length,\n commentsCreated: created\n };\n\n job.progress = {\n stage: 'creating',\n percentage: 100,\n message: `Complete! Created ${created} comments`\n };\n\n await this.updateJobProgress(job);\n console.log(`[CommentDetectionWorker] ✅ Created ${created}/${comments.length} comments`);\n }\n\n private async createCommentAnnotation(\n resourceId: ResourceId,\n userId_: string,\n comment: CommentMatch\n ): Promise<void> {\n const backendUrl = this.config.services.backend?.publicURL;\n\n if (!backendUrl) {\n throw new Error('Backend publicURL not configured');\n }\n\n const resourceUri = resourceIdToURI(resourceId, backendUrl);\n const annotationId = generateAnnotationId(backendUrl);\n\n // Create W3C-compliant annotation with motivation: \"commenting\"\n const annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n type: 'Annotation' as const,\n id: annotationId,\n motivation: 'commenting' as const,\n target: {\n type: 'SpecificResource' as const,\n source: resourceUri,\n selector: [\n {\n type: 'TextPositionSelector' as const,\n start: comment.start,\n end: comment.end\n },\n {\n type: 'TextQuoteSelector' as const,\n exact: comment.exact,\n prefix: comment.prefix || '',\n suffix: comment.suffix || ''\n }\n ]\n },\n body: [\n {\n type: 'TextualBody' as const,\n value: comment.comment,\n purpose: 'commenting' as const,\n format: 'text/plain',\n language: 'en'\n }\n ]\n };\n\n // Append annotation.added event to Event Store\n await this.eventStore.appendEvent({\n type: 'annotation.added',\n resourceId,\n userId: userId(userId_),\n version: 1,\n payload: {\n annotation\n }\n });\n\n console.log(`[CommentDetectionWorker] Created comment annotation ${annotationId} for \"${comment.exact.substring(0, 50)}...\"`);\n }\n}\n","/**\n * Highlight Detection Worker\n *\n * Processes highlight-detection jobs: runs AI inference to find passages\n * that should be highlighted and creates highlight annotations.\n */\n\nimport { JobWorker } from '@semiont/jobs';\nimport type { Job, HighlightDetectionJob, JobQueue } from '@semiont/jobs';\nimport { ResourceContext, AnnotationDetection } from '../..';\nimport { EventStore, generateAnnotationId } from '@semiont/event-sourcing';\nimport { resourceIdToURI } from '@semiont/core';\nimport type { EnvironmentConfig, ResourceId } from '@semiont/core';\nimport { userId } from '@semiont/core';\nimport type { HighlightMatch } from '@semiont/inference';\n\nexport class HighlightDetectionWorker extends JobWorker {\n private isFirstProgress = true;\n\n constructor(\n jobQueue: JobQueue,\n private config: EnvironmentConfig,\n private eventStore: EventStore\n ) {\n super(jobQueue);\n }\n\n protected getWorkerName(): string {\n return 'HighlightDetectionWorker';\n }\n\n protected canProcessJob(job: Job): boolean {\n return job.type === 'highlight-detection';\n }\n\n protected async executeJob(job: Job): Promise<void> {\n if (job.type !== 'highlight-detection') {\n throw new Error(`Invalid job type: ${job.type}`);\n }\n\n // Reset progress tracking\n this.isFirstProgress = true;\n await this.processHighlightDetectionJob(job);\n }\n\n /**\n * Override updateJobProgress to emit events to Event Store\n */\n protected override async updateJobProgress(job: Job): Promise<void> {\n // Call parent to update filesystem\n await super.updateJobProgress(job);\n\n if (job.type !== 'highlight-detection') return;\n\n const hlJob = job as HighlightDetectionJob;\n if (!hlJob.progress) return;\n\n const baseEvent = {\n resourceId: hlJob.resourceId,\n userId: hlJob.userId,\n version: 1,\n };\n\n // Determine if this is completion (100% and has result)\n const isComplete = hlJob.progress.percentage === 100 && hlJob.result;\n\n if (this.isFirstProgress) {\n // First progress update - emit job.started\n this.isFirstProgress = false;\n await this.eventStore.appendEvent({\n type: 'job.started',\n ...baseEvent,\n payload: {\n jobId: hlJob.id,\n jobType: hlJob.type,\n },\n });\n } else if (isComplete) {\n // Final update - emit job.completed\n await this.eventStore.appendEvent({\n type: 'job.completed',\n ...baseEvent,\n payload: {\n jobId: hlJob.id,\n jobType: hlJob.type,\n result: hlJob.result,\n },\n });\n } else {\n // Intermediate progress - emit job.progress\n await this.eventStore.appendEvent({\n type: 'job.progress',\n ...baseEvent,\n payload: {\n jobId: hlJob.id,\n jobType: hlJob.type,\n progress: hlJob.progress,\n },\n });\n }\n }\n\n protected override async handleJobFailure(job: Job, error: any): Promise<void> {\n // Call parent to handle the failure logic\n await super.handleJobFailure(job, error);\n\n // If job permanently failed, emit job.failed event\n if (job.status === 'failed' && job.type === 'highlight-detection') {\n const hlJob = job as HighlightDetectionJob;\n\n // Log the full error details to backend logs (already logged by parent)\n // Send generic error message to frontend\n await this.eventStore.appendEvent({\n type: 'job.failed',\n resourceId: hlJob.resourceId,\n userId: hlJob.userId,\n version: 1,\n payload: {\n jobId: hlJob.id,\n jobType: hlJob.type,\n error: 'Highlight detection failed. Please try again later.',\n },\n });\n }\n }\n\n private async processHighlightDetectionJob(job: HighlightDetectionJob): Promise<void> {\n console.log(`[HighlightDetectionWorker] Processing highlight detection for resource ${job.resourceId} (job: ${job.id})`);\n\n // Fetch resource content\n const resource = await ResourceContext.getResourceMetadata(job.resourceId, this.config);\n\n if (!resource) {\n throw new Error(`Resource ${job.resourceId} not found`);\n }\n\n // Emit job.started and start analyzing\n job.progress = {\n stage: 'analyzing',\n percentage: 10,\n message: 'Loading resource...'\n };\n await this.updateJobProgress(job);\n\n // Update progress\n job.progress = {\n stage: 'analyzing',\n percentage: 30,\n message: 'Analyzing text...'\n };\n await this.updateJobProgress(job);\n\n // Use AI to detect highlights\n const highlights = await AnnotationDetection.detectHighlights(\n job.resourceId,\n this.config,\n job.instructions,\n job.density\n );\n\n console.log(`[HighlightDetectionWorker] Found ${highlights.length} highlights to create`);\n\n // Update progress\n job.progress = {\n stage: 'creating',\n percentage: 60,\n message: `Creating ${highlights.length} annotations...`\n };\n await this.updateJobProgress(job);\n\n // Create annotations for each highlight\n let created = 0;\n for (const highlight of highlights) {\n try {\n await this.createHighlightAnnotation(job.resourceId, job.userId, highlight);\n created++;\n } catch (error) {\n console.error(`[HighlightDetectionWorker] Failed to create highlight:`, error);\n }\n }\n\n // Complete job\n job.result = {\n highlightsFound: highlights.length,\n highlightsCreated: created\n };\n\n job.progress = {\n stage: 'creating',\n percentage: 100,\n message: `Complete! Created ${created} highlights`\n };\n\n await this.updateJobProgress(job);\n console.log(`[HighlightDetectionWorker] ✅ Created ${created}/${highlights.length} highlights`);\n }\n\n private async createHighlightAnnotation(\n resourceId: ResourceId,\n creatorUserId: string,\n highlight: HighlightMatch\n ): Promise<void> {\n const backendUrl = this.config.services.backend?.publicURL;\n if (!backendUrl) throw new Error('Backend publicURL not configured');\n\n const annotationId = generateAnnotationId(backendUrl);\n const resourceUri = resourceIdToURI(resourceId, backendUrl);\n\n // Create W3C annotation with motivation: highlighting\n // Use both TextPositionSelector and TextQuoteSelector (with prefix/suffix for fuzzy anchoring)\n const annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n 'id': annotationId,\n 'motivation': 'highlighting' as const,\n 'creator': userId(creatorUserId),\n 'created': new Date().toISOString(),\n 'target': {\n type: 'SpecificResource' as const,\n source: resourceUri,\n selector: [\n {\n type: 'TextPositionSelector' as const,\n start: highlight.start,\n end: highlight.end,\n },\n {\n type: 'TextQuoteSelector' as const,\n exact: highlight.exact,\n ...(highlight.prefix && { prefix: highlight.prefix }),\n ...(highlight.suffix && { suffix: highlight.suffix }),\n },\n ]\n },\n 'body': [] // Empty body for highlights\n };\n\n await this.eventStore.appendEvent({\n type: 'annotation.added',\n resourceId,\n userId: userId(creatorUserId),\n version: 1,\n payload: { annotation }\n });\n }\n}\n","/**\n * Assessment Detection Worker\n *\n * Processes assessment-detection jobs: runs AI inference to assess/evaluate\n * passages in the text and creates assessment annotations.\n */\n\nimport { JobWorker } from '@semiont/jobs';\nimport type { Job, AssessmentDetectionJob, JobQueue } from '@semiont/jobs';\nimport { ResourceContext, AnnotationDetection } from '../..';\nimport { EventStore, generateAnnotationId } from '@semiont/event-sourcing';\nimport { resourceIdToURI } from '@semiont/core';\nimport type { EnvironmentConfig, ResourceId } from '@semiont/core';\nimport { userId } from '@semiont/core';\nimport type { AssessmentMatch } from '@semiont/inference';\n\nexport class AssessmentDetectionWorker extends JobWorker {\n private isFirstProgress = true;\n\n constructor(\n jobQueue: JobQueue,\n private config: EnvironmentConfig,\n private eventStore: EventStore\n ) {\n super(jobQueue);\n }\n\n protected getWorkerName(): string {\n return 'AssessmentDetectionWorker';\n }\n\n protected canProcessJob(job: Job): boolean {\n return job.type === 'assessment-detection';\n }\n\n protected async executeJob(job: Job): Promise<void> {\n if (job.type !== 'assessment-detection') {\n throw new Error(`Invalid job type: ${job.type}`);\n }\n\n // Reset progress tracking\n this.isFirstProgress = true;\n await this.processAssessmentDetectionJob(job);\n }\n\n /**\n * Override updateJobProgress to emit events to Event Store\n */\n protected override async updateJobProgress(job: Job): Promise<void> {\n // Call parent to update filesystem\n await super.updateJobProgress(job);\n\n if (job.type !== 'assessment-detection') return;\n\n const assJob = job as AssessmentDetectionJob;\n if (!assJob.progress) return;\n\n const baseEvent = {\n resourceId: assJob.resourceId,\n userId: assJob.userId,\n version: 1,\n };\n\n // Determine if this is completion (100% and has result)\n const isComplete = assJob.progress.percentage === 100 && assJob.result;\n\n if (this.isFirstProgress) {\n // First progress update - emit job.started\n this.isFirstProgress = false;\n await this.eventStore.appendEvent({\n type: 'job.started',\n ...baseEvent,\n payload: {\n jobId: assJob.id,\n jobType: assJob.type,\n },\n });\n } else if (isComplete) {\n // Final update - emit job.completed\n await this.eventStore.appendEvent({\n type: 'job.completed',\n ...baseEvent,\n payload: {\n jobId: assJob.id,\n jobType: assJob.type,\n result: assJob.result,\n },\n });\n } else {\n // Intermediate progress - emit job.progress\n await this.eventStore.appendEvent({\n type: 'job.progress',\n ...baseEvent,\n payload: {\n jobId: assJob.id,\n jobType: assJob.type,\n progress: assJob.progress,\n },\n });\n }\n }\n\n protected override async handleJobFailure(job: Job, error: any): Promise<void> {\n // Call parent to handle the failure logic\n await super.handleJobFailure(job, error);\n\n // If job permanently failed, emit job.failed event\n if (job.status === 'failed' && job.type === 'assessment-detection') {\n const aJob = job as AssessmentDetectionJob;\n\n // Log the full error details to backend logs (already logged by parent)\n // Send generic error message to frontend\n await this.eventStore.appendEvent({\n type: 'job.failed',\n resourceId: aJob.resourceId,\n userId: aJob.userId,\n version: 1,\n payload: {\n jobId: aJob.id,\n jobType: aJob.type,\n error: 'Assessment detection failed. Please try again later.',\n },\n });\n }\n }\n\n private async processAssessmentDetectionJob(job: AssessmentDetectionJob): Promise<void> {\n console.log(`[AssessmentDetectionWorker] Processing assessment detection for resource ${job.resourceId} (job: ${job.id})`);\n\n // Fetch resource content\n const resource = await ResourceContext.getResourceMetadata(job.resourceId, this.config);\n\n if (!resource) {\n throw new Error(`Resource ${job.resourceId} not found`);\n }\n\n // Emit job.started and start analyzing\n job.progress = {\n stage: 'analyzing',\n percentage: 10,\n message: 'Loading resource...'\n };\n await this.updateJobProgress(job);\n\n // Update progress\n job.progress = {\n stage: 'analyzing',\n percentage: 30,\n message: 'Analyzing text...'\n };\n await this.updateJobProgress(job);\n\n // Use AI to detect assessments\n const assessments = await AnnotationDetection.detectAssessments(\n job.resourceId,\n this.config,\n job.instructions,\n job.tone,\n job.density\n );\n\n console.log(`[AssessmentDetectionWorker] Found ${assessments.length} assessments to create`);\n\n // Update progress\n job.progress = {\n stage: 'creating',\n percentage: 60,\n message: `Creating ${assessments.length} annotations...`\n };\n await this.updateJobProgress(job);\n\n // Create annotations for each assessment\n let created = 0;\n for (const assessment of assessments) {\n try {\n await this.createAssessmentAnnotation(job.resourceId, job.userId, assessment);\n created++;\n } catch (error) {\n console.error(`[AssessmentDetectionWorker] Failed to create assessment:`, error);\n }\n }\n\n // Complete job\n job.result = {\n assessmentsFound: assessments.length,\n assessmentsCreated: created\n };\n\n job.progress = {\n stage: 'creating',\n percentage: 100,\n message: `Complete! Created ${created} assessments`\n };\n\n await this.updateJobProgress(job);\n console.log(`[AssessmentDetectionWorker] ✅ Created ${created}/${assessments.length} assessments`);\n }\n\n private async createAssessmentAnnotation(\n resourceId: ResourceId,\n creatorUserId: string,\n assessment: AssessmentMatch\n ): Promise<void> {\n const backendUrl = this.config.services.backend?.publicURL;\n if (!backendUrl) throw new Error('Backend publicURL not configured');\n\n const annotationId = generateAnnotationId(backendUrl);\n const resourceUri = resourceIdToURI(resourceId, backendUrl);\n\n // Create W3C annotation with motivation: assessing\n // Use both TextPositionSelector and TextQuoteSelector (with prefix/suffix for fuzzy anchoring)\n const annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n 'id': annotationId,\n 'motivation': 'assessing' as const,\n 'creator': userId(creatorUserId),\n 'created': new Date().toISOString(),\n 'target': {\n type: 'SpecificResource' as const,\n source: resourceUri,\n selector: [\n {\n type: 'TextPositionSelector' as const,\n start: assessment.start,\n end: assessment.end,\n },\n {\n type: 'TextQuoteSelector' as const,\n exact: assessment.exact,\n ...(assessment.prefix && { prefix: assessment.prefix }),\n ...(assessment.suffix && { suffix: assessment.suffix }),\n },\n ]\n },\n 'body': {\n type: 'TextualBody' as const,\n value: assessment.assessment,\n format: 'text/plain'\n }\n };\n\n await this.eventStore.appendEvent({\n type: 'annotation.added',\n resourceId,\n userId: userId(creatorUserId),\n version: 1,\n payload: { annotation }\n });\n }\n}\n","/**\n * Tag Detection Worker\n *\n * Processes tag-detection jobs: runs AI inference to identify passages\n * serving specific structural roles (IRAC, IMRAD, Toulmin, etc.) and\n * creates tag annotations with dual-body structure.\n */\n\nimport { JobWorker } from '@semiont/jobs';\nimport type { Job, TagDetectionJob, JobQueue } from '@semiont/jobs';\nimport { ResourceContext, AnnotationDetection } from '../..';\nimport { EventStore, generateAnnotationId } from '@semiont/event-sourcing';\nimport { resourceIdToURI } from '@semiont/core';\nimport { getTagSchema } from '@semiont/ontology';\nimport type { EnvironmentConfig, ResourceId } from '@semiont/core';\nimport { userId } from '@semiont/core';\nimport type { TagMatch } from '@semiont/inference';\n\nexport class TagDetectionWorker extends JobWorker {\n private isFirstProgress = true;\n\n constructor(\n jobQueue: JobQueue,\n private config: EnvironmentConfig,\n private eventStore: EventStore\n ) {\n super(jobQueue);\n }\n\n protected getWorkerName(): string {\n return 'TagDetectionWorker';\n }\n\n protected canProcessJob(job: Job): boolean {\n return job.type === 'tag-detection';\n }\n\n protected async executeJob(job: Job): Promise<void> {\n if (job.type !== 'tag-detection') {\n throw new Error(`Invalid job type: ${job.type}`);\n }\n\n // Reset progress tracking\n this.isFirstProgress = true;\n await this.processTagDetectionJob(job);\n }\n\n /**\n * Override updateJobProgress to emit events to Event Store\n */\n protected override async updateJobProgress(job: Job): Promise<void> {\n // Call parent to update filesystem\n await super.updateJobProgress(job);\n\n if (job.type !== 'tag-detection') return;\n\n const tdJob = job as TagDetectionJob;\n if (!tdJob.progress) return;\n\n const baseEvent = {\n resourceId: tdJob.resourceId,\n userId: tdJob.userId,\n version: 1,\n };\n\n // Determine if this is completion (100% and has result)\n const isComplete = tdJob.progress.percentage === 100 && tdJob.result;\n\n if (this.isFirstProgress) {\n // First progress update - emit job.started\n this.isFirstProgress = false;\n await this.eventStore.appendEvent({\n type: 'job.started',\n ...baseEvent,\n payload: {\n jobId: tdJob.id,\n jobType: tdJob.type,\n },\n });\n } else if (isComplete) {\n // Final update - emit job.completed\n await this.eventStore.appendEvent({\n type: 'job.completed',\n ...baseEvent,\n payload: {\n jobId: tdJob.id,\n jobType: tdJob.type,\n result: tdJob.result,\n },\n });\n } else {\n // Intermediate progress - emit job.progress\n await this.eventStore.appendEvent({\n type: 'job.progress',\n ...baseEvent,\n payload: {\n jobId: tdJob.id,\n jobType: tdJob.type,\n progress: tdJob.progress,\n },\n });\n }\n }\n\n protected override async handleJobFailure(job: Job, error: any): Promise<void> {\n // Call parent to handle the failure logic\n await super.handleJobFailure(job, error);\n\n // If job permanently failed, emit job.failed event\n if (job.status === 'failed' && job.type === 'tag-detection') {\n const tdJob = job as TagDetectionJob;\n\n await this.eventStore.appendEvent({\n type: 'job.failed',\n resourceId: tdJob.resourceId,\n userId: tdJob.userId,\n version: 1,\n payload: {\n jobId: tdJob.id,\n jobType: tdJob.type,\n error: 'Tag detection failed. Please try again later.',\n },\n });\n }\n }\n\n private async processTagDetectionJob(job: TagDetectionJob): Promise<void> {\n console.log(`[TagDetectionWorker] Processing tag detection for resource ${job.resourceId} (job: ${job.id})`);\n\n // Validate schema\n const schema = getTagSchema(job.schemaId);\n if (!schema) {\n throw new Error(`Invalid tag schema: ${job.schemaId}`);\n }\n\n // Validate categories\n for (const category of job.categories) {\n if (!schema.tags.some(t => t.name === category)) {\n throw new Error(`Invalid category \"${category}\" for schema ${job.schemaId}`);\n }\n }\n\n // Fetch resource content\n const resource = await ResourceContext.getResourceMetadata(job.resourceId, this.config);\n if (!resource) {\n throw new Error(`Resource ${job.resourceId} not found`);\n }\n\n // Emit job.started\n job.progress = {\n stage: 'analyzing',\n percentage: 10,\n processedCategories: 0,\n totalCategories: job.categories.length,\n message: 'Loading resource...'\n };\n await this.updateJobProgress(job);\n\n // Process each category separately\n const allTags: TagMatch[] = [];\n const byCategory: Record<string, number> = {};\n\n for (let i = 0; i < job.categories.length; i++) {\n const category = job.categories[i]!; // Safe: i < length check guarantees element exists\n\n job.progress = {\n stage: 'analyzing',\n percentage: 10 + Math.floor((i / job.categories.length) * 50),\n currentCategory: category,\n processedCategories: i + 1,\n totalCategories: job.categories.length,\n message: `Analyzing ${category}...`\n };\n await this.updateJobProgress(job);\n\n // Detect tags for this category\n const tags = await AnnotationDetection.detectTags(\n job.resourceId,\n this.config,\n job.schemaId,\n category\n );\n console.log(`[TagDetectionWorker] Found ${tags.length} tags for category \"${category}\"`);\n\n allTags.push(...tags);\n byCategory[category] = tags.length;\n }\n\n // Create annotations\n job.progress = {\n stage: 'creating',\n percentage: 60,\n processedCategories: job.categories.length,\n totalCategories: job.categories.length,\n message: `Creating ${allTags.length} tag annotations...`\n };\n await this.updateJobProgress(job);\n\n let created = 0;\n for (const tag of allTags) {\n try {\n await this.createTagAnnotation(job.resourceId, job.userId, job.schemaId, tag);\n created++;\n } catch (error) {\n console.error(`[TagDetectionWorker] Failed to create tag:`, error);\n }\n }\n\n // Complete job\n job.result = {\n tagsFound: allTags.length,\n tagsCreated: created,\n byCategory\n };\n\n job.progress = {\n stage: 'creating',\n percentage: 100,\n processedCategories: job.categories.length,\n totalCategories: job.categories.length,\n message: `Complete! Created ${created} tags`\n };\n\n await this.updateJobProgress(job);\n console.log(`[TagDetectionWorker] ✅ Created ${created}/${allTags.length} tags across ${job.categories.length} categories`);\n }\n\n private async createTagAnnotation(\n resourceId: ResourceId,\n userId_: string,\n schemaId: string,\n tag: TagMatch\n ): Promise<void> {\n const backendUrl = this.config.services.backend?.publicURL;\n\n if (!backendUrl) {\n throw new Error('Backend publicURL not configured');\n }\n\n const resourceUri = resourceIdToURI(resourceId, backendUrl);\n const annotationId = generateAnnotationId(backendUrl);\n\n // Create W3C-compliant annotation with dual-body structure:\n // 1. purpose: \"tagging\" with category value\n // 2. purpose: \"classifying\" with schema ID\n const annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n type: 'Annotation' as const,\n id: annotationId,\n motivation: 'tagging' as const,\n target: {\n type: 'SpecificResource' as const,\n source: resourceUri,\n selector: [\n {\n type: 'TextPositionSelector' as const,\n start: tag.start,\n end: tag.end\n },\n {\n type: 'TextQuoteSelector' as const,\n exact: tag.exact,\n prefix: tag.prefix || '',\n suffix: tag.suffix || ''\n }\n ]\n },\n body: [\n {\n type: 'TextualBody' as const,\n value: tag.category,\n purpose: 'tagging' as const,\n format: 'text/plain',\n language: 'en'\n },\n {\n type: 'TextualBody' as const,\n value: schemaId,\n purpose: 'classifying' as const,\n format: 'text/plain'\n }\n ]\n };\n\n // Append annotation.added event to Event Store\n await this.eventStore.appendEvent({\n type: 'annotation.added',\n resourceId,\n userId: userId(userId_),\n version: 1,\n payload: {\n annotation\n }\n });\n\n console.log(`[TagDetectionWorker] Created tag annotation ${annotationId} for \"${tag.category}\": \"${tag.exact.substring(0, 50)}...\"`);\n }\n}\n","/**\n * Reference Detection Worker\n *\n * Processes detection jobs: runs AI inference to find entities in resources\n * and emits reference.created events for each detected entity.\n *\n * This worker is INDEPENDENT of HTTP clients - it just processes jobs and emits events.\n */\n\nimport { JobWorker } from '@semiont/jobs';\nimport type { Job, DetectionJob, JobQueue } from '@semiont/jobs';\nimport { ResourceContext } from '../..';\nimport { EventStore, generateAnnotationId } from '@semiont/event-sourcing';\nimport { resourceIdToURI } from '@semiont/core';\nimport type { EnvironmentConfig } from '@semiont/core';\nimport {\n type components,\n getPrimaryRepresentation,\n decodeRepresentation,\n validateAndCorrectOffsets,\n} from '@semiont/api-client';\nimport { extractEntities } from '@semiont/inference';\nimport { FilesystemRepresentationStore } from '@semiont/content';\n\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\n\nexport interface DetectedAnnotation {\n annotation: {\n selector: {\n start: number;\n end: number;\n exact: string;\n prefix?: string;\n suffix?: string;\n };\n entityTypes: string[];\n };\n}\n\nexport class ReferenceDetectionWorker extends JobWorker {\n constructor(\n jobQueue: JobQueue,\n private config: EnvironmentConfig,\n private eventStore: EventStore\n ) {\n super(jobQueue);\n }\n\n protected getWorkerName(): string {\n return 'ReferenceDetectionWorker';\n }\n\n protected canProcessJob(job: Job): boolean {\n return job.type === 'detection';\n }\n\n protected async executeJob(job: Job): Promise<void> {\n if (job.type !== 'detection') {\n throw new Error(`Invalid job type: ${job.type}`);\n }\n\n await this.processDetectionJob(job);\n }\n\n /**\n * Detect entity references in resource using AI\n * Self-contained implementation for reference detection\n *\n * Public for testing charset handling - see entity-detection-charset.test.ts\n */\n public async detectReferences(\n resource: ResourceDescriptor,\n entityTypes: string[],\n includeDescriptiveReferences: boolean = false\n ): Promise<DetectedAnnotation[]> {\n console.log(`Detecting entities of types: ${entityTypes.join(', ')}${includeDescriptiveReferences ? ' (including descriptive references)' : ''}`);\n\n const detectedAnnotations: DetectedAnnotation[] = [];\n\n // Get primary representation\n const primaryRep = getPrimaryRepresentation(resource);\n if (!primaryRep) return detectedAnnotations;\n\n // Only process text content (check base media type, ignoring charset parameters)\n const mediaType = primaryRep.mediaType;\n const baseMediaType = mediaType?.split(';')[0]?.trim() || '';\n if (baseMediaType === 'text/plain' || baseMediaType === 'text/markdown') {\n // Load content from representation store using content-addressed lookup\n if (!primaryRep.checksum || !primaryRep.mediaType) return detectedAnnotations;\n\n const basePath = this.config.services.filesystem!.path;\n const projectRoot = this.config._metadata?.projectRoot;\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n const contentBuffer = await repStore.retrieve(primaryRep.checksum, primaryRep.mediaType);\n const content = decodeRepresentation(contentBuffer, primaryRep.mediaType);\n\n // Use AI to extract entities (with optional anaphoric/cataphoric references)\n const extractedEntities = await extractEntities(content, entityTypes, this.config, includeDescriptiveReferences);\n\n // Validate and correct AI's offsets, then extract proper context\n // AI sometimes returns offsets that don't match the actual text position\n for (const entity of extractedEntities) {\n try {\n const validated = validateAndCorrectOffsets(\n content,\n entity.startOffset,\n entity.endOffset,\n entity.exact\n );\n\n const annotation: DetectedAnnotation = {\n annotation: {\n selector: {\n start: validated.start,\n end: validated.end,\n exact: validated.exact,\n prefix: validated.prefix,\n suffix: validated.suffix,\n },\n entityTypes: [entity.entityType],\n },\n };\n detectedAnnotations.push(annotation);\n } catch (error) {\n console.warn(`[ReferenceDetectionWorker] Skipping invalid entity \"${entity.exact}\":`, error);\n // Skip this entity - AI hallucinated text that doesn't exist\n }\n }\n }\n\n return detectedAnnotations;\n }\n\n private async processDetectionJob(job: DetectionJob): Promise<void> {\n console.log(`[ReferenceDetectionWorker] Processing detection for resource ${job.resourceId} (job: ${job.id})`);\n console.log(`[ReferenceDetectionWorker] 🔍 Entity types: ${job.entityTypes.join(', ')}`);\n\n // Fetch resource content\n const resource = await ResourceContext.getResourceMetadata(job.resourceId, this.config);\n\n if (!resource) {\n throw new Error(`Resource ${job.resourceId} not found`);\n }\n\n let totalFound = 0;\n let totalEmitted = 0;\n let totalErrors = 0;\n\n // Emit job.started before processing\n job.progress = {\n totalEntityTypes: job.entityTypes.length,\n processedEntityTypes: 0,\n entitiesFound: 0,\n entitiesEmitted: 0\n };\n await this.updateJobProgress(job);\n\n // Process each entity type\n for (let i = 0; i < job.entityTypes.length; i++) {\n const entityType = job.entityTypes[i];\n\n if (!entityType) continue;\n\n console.log(`[ReferenceDetectionWorker] 🤖 [${i + 1}/${job.entityTypes.length}] Detecting ${entityType}...`);\n\n // Detect entities using AI (loads content from filesystem internally)\n const detectedAnnotations = await this.detectReferences(resource, [entityType], job.includeDescriptiveReferences);\n\n totalFound += detectedAnnotations.length;\n console.log(`[ReferenceDetectionWorker] ✅ Found ${detectedAnnotations.length} ${entityType} entities`);\n\n // Emit events for each detected entity\n // This happens INDEPENDENT of any HTTP client!\n for (let idx = 0; idx < detectedAnnotations.length; idx++) {\n const detected = detectedAnnotations[idx];\n\n if (!detected) {\n console.warn(`[ReferenceDetectionWorker] Skipping undefined entity at index ${idx}`);\n continue;\n }\n\n let referenceId: string;\n try {\n const backendUrl = this.config.services.backend?.publicURL;\n if (!backendUrl) {\n throw new Error('Backend publicURL not configured');\n }\n referenceId = generateAnnotationId(backendUrl);\n } catch (error) {\n console.error(`[ReferenceDetectionWorker] Failed to generate annotation ID:`, error);\n job.status = 'failed';\n job.error = 'Configuration error: Backend publicURL not set';\n await this.updateJobProgress(job);\n return;\n }\n\n try {\n await this.eventStore.appendEvent({\n type: 'annotation.added',\n resourceId: job.resourceId,\n userId: job.userId,\n version: 1,\n payload: {\n annotation: {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n id: referenceId,\n motivation: 'linking' as const,\n target: {\n source: resourceIdToURI(job.resourceId, this.config.services.backend!.publicURL), // Convert to full URI\n selector: [\n {\n type: 'TextPositionSelector',\n start: detected.annotation.selector.start,\n end: detected.annotation.selector.end,\n },\n {\n type: 'TextQuoteSelector',\n exact: detected.annotation.selector.exact,\n ...(detected.annotation.selector.prefix && { prefix: detected.annotation.selector.prefix }),\n ...(detected.annotation.selector.suffix && { suffix: detected.annotation.selector.suffix }),\n },\n ],\n },\n body: (detected.annotation.entityTypes || []).map(et => ({\n type: 'TextualBody' as const,\n value: et,\n purpose: 'tagging' as const,\n })),\n modified: new Date().toISOString(),\n },\n },\n });\n\n totalEmitted++;\n\n if ((idx + 1) % 10 === 0 || idx === detectedAnnotations.length - 1) {\n console.log(`[ReferenceDetectionWorker] 📤 Emitted ${idx + 1}/${detectedAnnotations.length} events for ${entityType}`);\n }\n\n } catch (error) {\n totalErrors++;\n console.error(`[ReferenceDetectionWorker] ❌ Failed to emit event for ${referenceId}:`, error);\n // Continue processing other entities even if one fails\n }\n }\n\n console.log(`[ReferenceDetectionWorker] ✅ Completed ${entityType}: ${detectedAnnotations.length} found, ${detectedAnnotations.length - (totalErrors - (totalFound - totalEmitted))} emitted`);\n\n // Update progress after processing this entity type\n job.progress = {\n totalEntityTypes: job.entityTypes.length,\n processedEntityTypes: i + 1,\n currentEntityType: entityType,\n entitiesFound: totalFound,\n entitiesEmitted: totalEmitted\n };\n await this.updateJobProgress(job);\n }\n\n // Set final result\n job.result = {\n totalFound,\n totalEmitted,\n errors: totalErrors\n };\n\n console.log(`[ReferenceDetectionWorker] ✅ Detection complete: ${totalFound} entities found, ${totalEmitted} events emitted, ${totalErrors} errors`);\n }\n\n protected override async handleJobFailure(job: Job, error: any): Promise<void> {\n // Call parent to handle the failure logic\n await super.handleJobFailure(job, error);\n\n // If job permanently failed, emit job.failed event\n if (job.status === 'failed' && job.type === 'detection') {\n const detJob = job as DetectionJob;\n\n // Log the full error details to backend logs (already logged by parent)\n // Send generic error message to frontend\n await this.eventStore.appendEvent({\n type: 'job.failed',\n resourceId: detJob.resourceId,\n userId: detJob.userId,\n version: 1,\n payload: {\n jobId: detJob.id,\n jobType: detJob.type,\n error: 'Entity detection failed. Please try again later.',\n },\n });\n }\n }\n\n /**\n * Update job progress and emit events to Event Store\n * Overrides base class to also emit job progress events\n */\n protected override async updateJobProgress(job: Job): Promise<void> {\n // Call parent to update job queue\n await super.updateJobProgress(job);\n\n // Emit events for detection jobs\n if (job.type !== 'detection') {\n return;\n }\n\n const detJob = job as DetectionJob;\n\n const baseEvent = {\n resourceId: detJob.resourceId,\n userId: detJob.userId,\n version: 1,\n };\n\n // Require progress object to be present\n if (!detJob.progress) {\n return;\n }\n\n // Determine if this is the first progress update (job.started)\n const isFirstUpdate = detJob.progress.processedEntityTypes === 0;\n\n // Determine if this is the final update (job.completed)\n const isFinalUpdate =\n detJob.progress.processedEntityTypes === detJob.progress.totalEntityTypes &&\n detJob.progress.totalEntityTypes > 0;\n\n if (isFirstUpdate) {\n // First progress update - emit job.started\n await this.eventStore.appendEvent({\n type: 'job.started',\n ...baseEvent,\n payload: {\n jobId: detJob.id,\n jobType: detJob.type,\n totalSteps: detJob.entityTypes.length,\n },\n });\n } else if (isFinalUpdate) {\n // Final progress update - emit job.completed\n await this.eventStore.appendEvent({\n type: 'job.completed',\n ...baseEvent,\n payload: {\n jobId: detJob.id,\n jobType: detJob.type,\n foundCount: detJob.progress.entitiesFound,\n },\n });\n } else {\n // Intermediate progress - emit job.progress\n const percentage = Math.round((detJob.progress.processedEntityTypes / detJob.progress.totalEntityTypes) * 100);\n await this.eventStore.appendEvent({\n type: 'job.progress',\n ...baseEvent,\n payload: {\n jobId: detJob.id,\n jobType: detJob.type,\n percentage,\n currentStep: detJob.progress.currentEntityType,\n processedSteps: detJob.progress.processedEntityTypes,\n totalSteps: detJob.progress.totalEntityTypes,\n foundCount: detJob.progress.entitiesFound,\n },\n });\n }\n }\n}\n","/**\n * Generation Worker\n *\n * Processes generation jobs: runs AI inference to generate new resources\n * and emits resource.created and annotation.body.updated events.\n *\n * This worker is INDEPENDENT of HTTP clients - it just processes jobs and emits events.\n */\n\nimport { JobWorker } from '@semiont/jobs';\nimport type { Job, GenerationJob, JobQueue } from '@semiont/jobs';\nimport { FilesystemRepresentationStore } from '@semiont/content';\nimport { ResourceContext } from '../..';\nimport { generateResourceFromTopic } from '@semiont/inference';\nimport {\n getTargetSelector,\n getExactText,\n resourceUri,\n annotationUri,\n} from '@semiont/api-client';\nimport { getEntityTypes } from '@semiont/ontology';\nimport {\n CREATION_METHODS,\n generateUuid,\n type BodyOperation,\n resourceId,\n annotationId,\n} from '@semiont/core';\nimport { EventStore } from '@semiont/event-sourcing';\nimport type { EnvironmentConfig } from '@semiont/core';\n\nexport class GenerationWorker extends JobWorker {\n constructor(\n jobQueue: JobQueue,\n private config: EnvironmentConfig,\n private eventStore: EventStore\n ) {\n super(jobQueue);\n }\n\n protected getWorkerName(): string {\n return 'GenerationWorker';\n }\n\n protected canProcessJob(job: Job): boolean {\n return job.type === 'generation';\n }\n\n protected async executeJob(job: Job): Promise<void> {\n if (job.type !== 'generation') {\n throw new Error(`Invalid job type: ${job.type}`);\n }\n\n await this.processGenerationJob(job);\n }\n\n private async processGenerationJob(job: GenerationJob): Promise<void> {\n console.log(`[GenerationWorker] Processing generation for reference ${job.referenceId} (job: ${job.id})`);\n\n const basePath = this.config.services.filesystem!.path;\n const projectRoot = this.config._metadata?.projectRoot;\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n\n // Update progress: fetching\n job.progress = {\n stage: 'fetching',\n percentage: 20,\n message: 'Fetching source resource...'\n };\n console.log(`[GenerationWorker] 📥 ${job.progress.message}`);\n await this.updateJobProgress(job);\n\n // Fetch annotation from view storage\n // TODO: Once AnnotationContext is consolidated, use it here\n const { FilesystemViewStorage } = await import('@semiont/event-sourcing');\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n const view = await viewStorage.get(job.sourceResourceId);\n if (!view) {\n throw new Error(`Resource ${job.sourceResourceId} not found`);\n }\n const projection = view.annotations;\n\n // Construct full annotation URI for comparison\n const expectedAnnotationUri = `${this.config.services.backend!.publicURL}/annotations/${job.referenceId}`;\n const annotation = projection.annotations.find((a: any) =>\n a.id === expectedAnnotationUri && a.motivation === 'linking'\n );\n\n if (!annotation) {\n throw new Error(`Annotation ${job.referenceId} not found in resource ${job.sourceResourceId}`);\n }\n\n const sourceResource = await ResourceContext.getResourceMetadata(job.sourceResourceId, this.config);\n if (!sourceResource) {\n throw new Error(`Source resource ${job.sourceResourceId} not found`);\n }\n\n // Determine resource name\n const targetSelector = getTargetSelector(annotation.target);\n const resourceName = job.title || (targetSelector ? getExactText(targetSelector) : '') || 'New Resource';\n console.log(`[GenerationWorker] Generating resource: \"${resourceName}\"`);\n\n // Verify context is provided (required for generation)\n if (!job.context) {\n throw new Error('Generation context is required but was not provided in job');\n }\n console.log(`[GenerationWorker] Using pre-fetched context: ${job.context.sourceContext?.before?.length || 0} chars before, ${job.context.sourceContext?.selected?.length || 0} chars selected, ${job.context.sourceContext?.after?.length || 0} chars after`);\n\n // Update progress: generating (skip fetching context since it's already in job)\n job.progress = {\n stage: 'generating',\n percentage: 40,\n message: 'Creating content with AI...'\n };\n console.log(`[GenerationWorker] 🤖 ${job.progress.message}`);\n await this.updateJobProgress(job);\n\n // Generate content using AI with context from job\n const prompt = job.prompt || `Create a comprehensive resource about \"${resourceName}\"`;\n // Extract entity types from annotation body\n const annotationEntityTypes = getEntityTypes({ body: annotation.body });\n\n const generatedContent = await generateResourceFromTopic(\n resourceName,\n job.entityTypes || annotationEntityTypes,\n this.config,\n prompt,\n job.language,\n job.context, // NEW - context from job (passed from modal)\n job.temperature, // NEW - from job\n job.maxTokens // NEW - from job\n );\n\n console.log(`[GenerationWorker] ✅ Generated ${generatedContent.content.length} bytes of content`);\n\n // Update progress: creating\n job.progress = {\n stage: 'generating',\n percentage: 70,\n message: 'Content ready, creating resource...'\n };\n await this.updateJobProgress(job);\n\n // Generate resource ID\n const rId = resourceId(generateUuid());\n\n // Update progress: creating\n job.progress = {\n stage: 'creating',\n percentage: 85,\n message: 'Saving resource...'\n };\n console.log(`[GenerationWorker] 💾 ${job.progress.message}`);\n await this.updateJobProgress(job);\n\n // Save content to RepresentationStore\n const storedRep = await repStore.store(Buffer.from(generatedContent.content), {\n mediaType: 'text/markdown',\n rel: 'original',\n });\n console.log(`[GenerationWorker] ✅ Saved resource representation to filesystem: ${rId}`);\n\n // Emit resource.created event\n await this.eventStore.appendEvent({\n type: 'resource.created',\n resourceId: rId,\n userId: job.userId,\n version: 1,\n payload: {\n name: resourceName,\n format: 'text/markdown',\n contentChecksum: storedRep.checksum,\n creationMethod: CREATION_METHODS.GENERATED,\n entityTypes: job.entityTypes || annotationEntityTypes,\n language: job.language,\n isDraft: true,\n generatedFrom: job.referenceId,\n generationPrompt: undefined, // Could be added if we track the prompt\n },\n });\n console.log(`[GenerationWorker] Emitted resource.created event for ${rId}`);\n\n // Update progress: linking\n job.progress = {\n stage: 'linking',\n percentage: 95,\n message: 'Linking reference...'\n };\n console.log(`[GenerationWorker] 🔗 ${job.progress.message}`);\n await this.updateJobProgress(job);\n\n // Emit annotation.body.updated event to link the annotation to the new resource\n // Build full resource URI for the annotation body\n const newResourceUri = resourceUri(`${this.config.services.backend!.publicURL}/resources/${rId}`);\n\n const operations: BodyOperation[] = [{\n op: 'add',\n item: {\n type: 'SpecificResource',\n source: newResourceUri,\n purpose: 'linking',\n },\n }];\n\n // Extract annotation ID from full URI (format: http://host/annotations/{id})\n const annotationIdSegment = job.referenceId.split('/').pop()!;\n\n await this.eventStore.appendEvent({\n type: 'annotation.body.updated',\n resourceId: job.sourceResourceId,\n userId: job.userId,\n version: 1,\n payload: {\n annotationId: annotationId(annotationIdSegment),\n operations,\n },\n });\n console.log(`[GenerationWorker] ✅ Emitted annotation.body.updated event linking ${job.referenceId} → ${rId}`);\n\n // Set final result\n job.result = {\n resourceId: rId,\n resourceName\n };\n\n job.progress = {\n stage: 'linking',\n percentage: 100,\n message: 'Complete!'\n };\n await this.updateJobProgress(job);\n\n console.log(`[GenerationWorker] ✅ Generation complete: created resource ${rId}`);\n }\n\n /**\n * Update job progress and emit events to Event Store\n * Overrides base class to also emit job progress events\n */\n protected override async updateJobProgress(job: Job): Promise<void> {\n // Call parent to update job queue\n await super.updateJobProgress(job);\n\n // Emit events for generation jobs\n if (job.type !== 'generation') {\n return;\n }\n\n const genJob = job as GenerationJob;\n\n const baseEvent = {\n resourceId: genJob.sourceResourceId,\n userId: genJob.userId,\n version: 1,\n };\n\n // Emit appropriate event based on progress stage\n if (genJob.progress?.stage === 'fetching' && genJob.progress?.percentage === 20) {\n // First progress update - emit job.started\n await this.eventStore.appendEvent({\n type: 'job.started',\n ...baseEvent,\n payload: {\n jobId: genJob.id,\n jobType: genJob.type,\n totalSteps: 5, // fetching, generating, creating, linking, complete\n },\n });\n } else if (genJob.progress?.stage === 'linking' && genJob.progress?.percentage === 100) {\n // Final progress update - emit job.completed\n await this.eventStore.appendEvent({\n type: 'job.completed',\n ...baseEvent,\n payload: {\n jobId: genJob.id,\n jobType: genJob.type,\n resultResourceId: genJob.result?.resourceId,\n annotationUri: annotationUri(`${this.config.services.backend!.publicURL}/annotations/${genJob.referenceId}`),\n },\n });\n } else if (genJob.progress) {\n // Intermediate progress - emit job.progress\n await this.eventStore.appendEvent({\n type: 'job.progress',\n ...baseEvent,\n payload: {\n jobId: genJob.id,\n jobType: genJob.type,\n currentStep: genJob.progress.stage,\n percentage: genJob.progress.percentage,\n message: genJob.progress.message,\n },\n });\n }\n }\n}\n","// @semiont/make-meaning - Making meaning from resources\n// Transforms raw resources into meaningful, interconnected knowledge\n\n// Context assembly exports\nexport { ResourceContext } from './resource-context';\nexport type { ListResourcesFilters } from './resource-context';\nexport { AnnotationContext } from './annotation-context';\nexport type { BuildContextOptions } from './annotation-context';\nexport { GraphContext } from './graph-context';\n\n// Detection exports\nexport { AnnotationDetection } from './annotation-detection';\n\n// Re-export match types from @semiont/inference for convenience\nexport type {\n CommentMatch,\n HighlightMatch,\n AssessmentMatch,\n TagMatch,\n} from '@semiont/inference';\n\n// Job workers\nexport { CommentDetectionWorker } from './jobs/workers/comment-detection-worker';\nexport { HighlightDetectionWorker } from './jobs/workers/highlight-detection-worker';\nexport { AssessmentDetectionWorker } from './jobs/workers/assessment-detection-worker';\nexport { TagDetectionWorker } from './jobs/workers/tag-detection-worker';\nexport { ReferenceDetectionWorker } from './jobs/workers/reference-detection-worker';\nexport { GenerationWorker } from './jobs/workers/generation-worker';\n\n// Reasoning exports (future)\n// export { ResourceReasoning } from './resource-reasoning';\n\n// Placeholder for initial build\nexport const PACKAGE_NAME = '@semiont/make-meaning';\nexport const VERSION = '0.1.0';\n"],"mappings":"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","names":["resourceId","getPrimaryRepresentation","decodeRepresentation","FilesystemRepresentationStore","FilesystemViewStorage","annotationUri","resourceId","FilesystemViewStorage","FilesystemRepresentationStore","targetResourceId","getPrimaryRepresentation","decodeRepresentation","annotationId","resourceId","resourceUri","FilesystemRepresentationStore","getPrimaryRepresentation","decodeRepresentation","generateText","resourceId","resourceIdToURI","resourceId","resourceUri","annotationId","JobWorker","generateAnnotationId","resourceIdToURI","userId","JobWorker","resourceId","annotationId","resourceUri","JobWorker","generateAnnotationId","resourceIdToURI","userId","JobWorker","resourceId","annotationId","resourceUri","JobWorker","generateAnnotationId","resourceIdToURI","getTagSchema","userId","JobWorker","resourceId","resourceUri","annotationId","JobWorker","generateAnnotationId","resourceIdToURI","getPrimaryRepresentation","decodeRepresentation","FilesystemRepresentationStore","JobWorker","JobWorker","FilesystemRepresentationStore","getTargetSelector","getEntityTypes","JobWorker","FilesystemRepresentationStore","FilesystemViewStorage"]}
1
+ {"version":3,"sources":["../src/service.ts","../src/jobs/reference-detection-worker.ts","../src/detection/entity-extractor.ts","../src/jobs/generation-worker.ts","../src/generation/resource-generation.ts","../src/jobs/highlight-detection-worker.ts","../src/jobs/assessment-detection-worker.ts","../src/jobs/comment-detection-worker.ts","../src/jobs/tag-detection-worker.ts","../src/graph/consumer.ts","../src/resource-context.ts","../src/annotation-context.ts","../src/graph-context.ts","../src/annotation-detection.ts","../src/detection/motivation-prompts.ts","../src/detection/motivation-parsers.ts","../src/index.ts"],"sourcesContent":["/**\n * Make-Meaning Service\n *\n * Consolidates all meaning-making infrastructure:\n * - Job queue initialization\n * - Worker instantiation and startup\n * - Graph consumer (event-to-graph synchronization)\n *\n * Provides a clean interface similar to createEventStore():\n * const makeMeaning = await startMakeMeaning(config);\n */\n\nimport * as path from 'path';\nimport { JobQueue } from '@semiont/jobs';\nimport { createEventStore as createEventStoreCore, type EventStore } from '@semiont/event-sourcing';\nimport { FilesystemRepresentationStore, type RepresentationStore } from '@semiont/content';\nimport type { EnvironmentConfig } from '@semiont/core';\nimport { resourceId as makeResourceId } from '@semiont/core';\nimport { getInferenceClient, type InferenceClient } from '@semiont/inference';\nimport { getGraphDatabase, type GraphDatabase } from '@semiont/graph';\nimport { ReferenceDetectionWorker } from './jobs/reference-detection-worker';\nimport { GenerationWorker } from './jobs/generation-worker';\nimport { HighlightDetectionWorker } from './jobs/highlight-detection-worker';\nimport { AssessmentDetectionWorker } from './jobs/assessment-detection-worker';\nimport { CommentDetectionWorker } from './jobs/comment-detection-worker';\nimport { TagDetectionWorker } from './jobs/tag-detection-worker';\nimport { GraphDBConsumer } from './graph/consumer';\n\nexport interface MakeMeaningService {\n jobQueue: JobQueue;\n eventStore: EventStore;\n repStore: RepresentationStore;\n inferenceClient: InferenceClient;\n graphDb: GraphDatabase;\n workers: {\n detection: ReferenceDetectionWorker;\n generation: GenerationWorker;\n highlight: HighlightDetectionWorker;\n assessment: AssessmentDetectionWorker;\n comment: CommentDetectionWorker;\n tag: TagDetectionWorker;\n };\n graphConsumer: GraphDBConsumer;\n stop: () => Promise<void>;\n}\n\nexport async function startMakeMeaning(config: EnvironmentConfig): Promise<MakeMeaningService> {\n console.log('🧠 Starting Make-Meaning service...');\n\n // 1. Validate configuration\n const configuredPath = config.services?.filesystem?.path;\n if (!configuredPath) {\n throw new Error('services.filesystem.path is required for make-meaning service');\n }\n\n const baseUrl = config.services?.backend?.publicURL;\n if (!baseUrl) {\n throw new Error('services.backend.publicURL is required for make-meaning service');\n }\n\n // Resolve basePath to absolute path\n const projectRoot = config._metadata?.projectRoot;\n let basePath: string;\n if (path.isAbsolute(configuredPath)) {\n basePath = configuredPath;\n } else if (projectRoot) {\n basePath = path.resolve(projectRoot, configuredPath);\n } else {\n basePath = path.resolve(configuredPath);\n }\n\n // 2. Initialize job queue\n console.log('💼 Initializing job queue...');\n const jobQueue = new JobQueue({ dataDir: basePath });\n await jobQueue.initialize();\n console.log('✅ Job queue initialized');\n\n // 3. Create shared event store\n console.log('📊 Creating event store connection...');\n const eventStore = createEventStoreCore(basePath, baseUrl);\n\n // 4. Create shared representation store\n console.log('📦 Creating representation store...');\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n console.log('✅ Representation store created');\n\n // 5. Create inference client (shared across all workers)\n console.log('🤖 Creating inference client...');\n const inferenceClient = await getInferenceClient(config);\n console.log('✅ Inference client created');\n\n // 6. Create graph database connection\n console.log('📊 Connecting to graph database...');\n const graphDb = await getGraphDatabase(config);\n console.log('✅ Graph database connected');\n\n // 7. Start graph consumer\n console.log('🔄 Starting graph consumer...');\n const graphConsumer = new GraphDBConsumer(config, eventStore, graphDb);\n await graphConsumer.initialize();\n\n // Subscribe to all existing resources\n const allResourceIds = await eventStore.log.getAllResourceIds();\n console.log(`[GraphDBConsumer] Subscribing to ${allResourceIds.length} resources`);\n for (const resourceId of allResourceIds) {\n await graphConsumer.subscribeToResource(makeResourceId(resourceId as string));\n }\n console.log('✅ Graph consumer started');\n\n // 8. Instantiate workers\n console.log('👷 Creating workers...');\n const workers = {\n detection: new ReferenceDetectionWorker(jobQueue, config, eventStore, inferenceClient),\n generation: new GenerationWorker(jobQueue, config, eventStore, inferenceClient),\n highlight: new HighlightDetectionWorker(jobQueue, config, eventStore, inferenceClient),\n assessment: new AssessmentDetectionWorker(jobQueue, config, eventStore, inferenceClient),\n comment: new CommentDetectionWorker(jobQueue, config, eventStore, inferenceClient),\n tag: new TagDetectionWorker(jobQueue, config, eventStore, inferenceClient),\n };\n\n // 8. Start all workers (non-blocking)\n console.log('🚀 Starting workers...');\n workers.detection.start().catch((error: unknown) => {\n console.error('⚠️ Detection worker stopped:', error);\n });\n workers.generation.start().catch((error: unknown) => {\n console.error('⚠️ Generation worker stopped:', error);\n });\n workers.highlight.start().catch((error: unknown) => {\n console.error('⚠️ Highlight worker stopped:', error);\n });\n workers.assessment.start().catch((error: unknown) => {\n console.error('⚠️ Assessment worker stopped:', error);\n });\n workers.comment.start().catch((error: unknown) => {\n console.error('⚠️ Comment worker stopped:', error);\n });\n workers.tag.start().catch((error: unknown) => {\n console.error('⚠️ Tag worker stopped:', error);\n });\n console.log('✅ All workers started');\n\n console.log('✅ Make-Meaning service started');\n\n return {\n jobQueue,\n eventStore,\n repStore,\n inferenceClient,\n graphDb,\n workers,\n graphConsumer,\n stop: async () => {\n console.log('⏹️ Stopping Make-Meaning service...');\n await Promise.all([\n workers.detection.stop(),\n workers.generation.stop(),\n workers.highlight.stop(),\n workers.assessment.stop(),\n workers.comment.stop(),\n workers.tag.stop(),\n ]);\n await graphConsumer.stop();\n await graphDb.disconnect();\n console.log('✅ Make-Meaning service stopped');\n },\n };\n}\n","/**\n * Reference Detection Worker\n *\n * Processes detection jobs: runs AI inference to find entities in resources\n * and emits reference.created events for each detected entity.\n *\n * This worker is INDEPENDENT of HTTP clients - it just processes jobs and emits events.\n */\n\nimport { JobWorker } from '@semiont/jobs';\nimport type { AnyJob, DetectionJob, JobQueue, RunningJob, DetectionParams, DetectionProgress } from '@semiont/jobs';\nimport { ResourceContext } from '..';\nimport { EventStore, generateAnnotationId } from '@semiont/event-sourcing';\nimport { resourceIdToURI } from '@semiont/core';\nimport type { EnvironmentConfig } from '@semiont/core';\nimport {\n type components,\n getPrimaryRepresentation,\n decodeRepresentation,\n validateAndCorrectOffsets,\n} from '@semiont/api-client';\nimport { extractEntities } from '../detection/entity-extractor';\nimport { FilesystemRepresentationStore } from '@semiont/content';\nimport type { InferenceClient } from '@semiont/inference';\n\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\n\nexport interface DetectedAnnotation {\n annotation: {\n selector: {\n start: number;\n end: number;\n exact: string;\n prefix?: string;\n suffix?: string;\n };\n entityTypes: string[];\n };\n}\n\nexport class ReferenceDetectionWorker extends JobWorker {\n constructor(\n jobQueue: JobQueue,\n private config: EnvironmentConfig,\n private eventStore: EventStore,\n private inferenceClient: InferenceClient\n ) {\n super(jobQueue);\n }\n\n protected getWorkerName(): string {\n return 'ReferenceDetectionWorker';\n }\n\n protected canProcessJob(job: AnyJob): boolean {\n return job.metadata.type === 'detection';\n }\n\n protected async executeJob(job: AnyJob): Promise<void> {\n if (job.metadata.type !== 'detection') {\n throw new Error(`Invalid job type: ${job.metadata.type}`);\n }\n\n // Type guard: job must be running to execute\n if (job.status !== 'running') {\n throw new Error(`Job must be in running state to execute, got: ${job.status}`);\n }\n\n await this.processDetectionJob(job as RunningJob<DetectionParams, DetectionProgress>);\n }\n\n /**\n * Detect entity references in resource using AI\n * Self-contained implementation for reference detection\n *\n * Public for testing charset handling - see entity-detection-charset.test.ts\n */\n public async detectReferences(\n resource: ResourceDescriptor,\n entityTypes: string[],\n includeDescriptiveReferences: boolean = false\n ): Promise<DetectedAnnotation[]> {\n console.log(`Detecting entities of types: ${entityTypes.join(', ')}${includeDescriptiveReferences ? ' (including descriptive references)' : ''}`);\n\n const detectedAnnotations: DetectedAnnotation[] = [];\n\n // Get primary representation\n const primaryRep = getPrimaryRepresentation(resource);\n if (!primaryRep) return detectedAnnotations;\n\n // Only process text content (check base media type, ignoring charset parameters)\n const mediaType = primaryRep.mediaType;\n const baseMediaType = mediaType?.split(';')[0]?.trim() || '';\n if (baseMediaType === 'text/plain' || baseMediaType === 'text/markdown') {\n // Load content from representation store using content-addressed lookup\n if (!primaryRep.checksum || !primaryRep.mediaType) return detectedAnnotations;\n\n const basePath = this.config.services.filesystem!.path;\n const projectRoot = this.config._metadata?.projectRoot;\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n const contentBuffer = await repStore.retrieve(primaryRep.checksum, primaryRep.mediaType);\n const content = decodeRepresentation(contentBuffer, primaryRep.mediaType);\n\n // Use AI to extract entities (with optional anaphoric/cataphoric references)\n const extractedEntities = await extractEntities(content, entityTypes, this.inferenceClient, includeDescriptiveReferences);\n\n // Validate and correct AI's offsets, then extract proper context\n // AI sometimes returns offsets that don't match the actual text position\n for (const entity of extractedEntities) {\n try {\n const validated = validateAndCorrectOffsets(\n content,\n entity.startOffset,\n entity.endOffset,\n entity.exact\n );\n\n const annotation: DetectedAnnotation = {\n annotation: {\n selector: {\n start: validated.start,\n end: validated.end,\n exact: validated.exact,\n prefix: validated.prefix,\n suffix: validated.suffix,\n },\n entityTypes: [entity.entityType],\n },\n };\n detectedAnnotations.push(annotation);\n } catch (error) {\n console.warn(`[ReferenceDetectionWorker] Skipping invalid entity \"${entity.exact}\":`, error);\n // Skip this entity - AI hallucinated text that doesn't exist\n }\n }\n }\n\n return detectedAnnotations;\n }\n\n private async processDetectionJob(job: RunningJob<DetectionParams, DetectionProgress>): Promise<void> {\n console.log(`[ReferenceDetectionWorker] Processing detection for resource ${job.params.resourceId} (job: ${job.metadata.id})`);\n console.log(`[ReferenceDetectionWorker] 🔍 Entity types: ${job.params.entityTypes.join(', ')}`);\n\n // Fetch resource content\n const resource = await ResourceContext.getResourceMetadata(job.params.resourceId, this.config);\n\n if (!resource) {\n throw new Error(`Resource ${job.params.resourceId} not found`);\n }\n\n let totalFound = 0;\n let totalEmitted = 0;\n let totalErrors = 0;\n\n // Create updated job with initial progress\n let updatedJob: RunningJob<DetectionParams, DetectionProgress> = {\n ...job,\n progress: {\n totalEntityTypes: job.params.entityTypes.length,\n processedEntityTypes: 0,\n entitiesFound: 0,\n entitiesEmitted: 0\n }\n };\n await this.updateJobProgress(updatedJob);\n\n // Process each entity type\n for (let i = 0; i < job.params.entityTypes.length; i++) {\n const entityType = job.params.entityTypes[i];\n\n if (!entityType) continue;\n\n console.log(`[ReferenceDetectionWorker] 🤖 [${i + 1}/${job.params.entityTypes.length}] Detecting ${entityType}...`);\n\n // Detect entities using AI (loads content from filesystem internally)\n const detectedAnnotations = await this.detectReferences(resource, [entityType], job.params.includeDescriptiveReferences);\n\n totalFound += detectedAnnotations.length;\n console.log(`[ReferenceDetectionWorker] ✅ Found ${detectedAnnotations.length} ${entityType} entities`);\n\n // Emit events for each detected entity\n // This happens INDEPENDENT of any HTTP client!\n for (let idx = 0; idx < detectedAnnotations.length; idx++) {\n const detected = detectedAnnotations[idx];\n\n if (!detected) {\n console.warn(`[ReferenceDetectionWorker] Skipping undefined entity at index ${idx}`);\n continue;\n }\n\n let referenceId: string;\n try {\n const backendUrl = this.config.services.backend?.publicURL;\n if (!backendUrl) {\n throw new Error('Backend publicURL not configured');\n }\n referenceId = generateAnnotationId(backendUrl);\n } catch (error) {\n console.error(`[ReferenceDetectionWorker] Failed to generate annotation ID:`, error);\n throw new Error('Configuration error: Backend publicURL not set');\n }\n\n try {\n await this.eventStore.appendEvent({\n type: 'annotation.added',\n resourceId: job.params.resourceId,\n userId: job.metadata.userId,\n version: 1,\n payload: {\n annotation: {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n id: referenceId,\n motivation: 'linking' as const,\n target: {\n source: resourceIdToURI(job.params.resourceId, this.config.services.backend!.publicURL), // Convert to full URI\n selector: [\n {\n type: 'TextPositionSelector',\n start: detected.annotation.selector.start,\n end: detected.annotation.selector.end,\n },\n {\n type: 'TextQuoteSelector',\n exact: detected.annotation.selector.exact,\n ...(detected.annotation.selector.prefix && { prefix: detected.annotation.selector.prefix }),\n ...(detected.annotation.selector.suffix && { suffix: detected.annotation.selector.suffix }),\n },\n ],\n },\n body: (detected.annotation.entityTypes || []).map(et => ({\n type: 'TextualBody' as const,\n value: et,\n purpose: 'tagging' as const,\n })),\n modified: new Date().toISOString(),\n },\n },\n });\n\n totalEmitted++;\n\n if ((idx + 1) % 10 === 0 || idx === detectedAnnotations.length - 1) {\n console.log(`[ReferenceDetectionWorker] 📤 Emitted ${idx + 1}/${detectedAnnotations.length} events for ${entityType}`);\n }\n\n } catch (error) {\n totalErrors++;\n console.error(`[ReferenceDetectionWorker] ❌ Failed to emit event for ${referenceId}:`, error);\n // Continue processing other entities even if one fails\n }\n }\n\n console.log(`[ReferenceDetectionWorker] ✅ Completed ${entityType}: ${detectedAnnotations.length} found, ${detectedAnnotations.length - (totalErrors - (totalFound - totalEmitted))} emitted`);\n\n // Update progress after processing this entity type\n updatedJob = {\n ...updatedJob,\n progress: {\n totalEntityTypes: job.params.entityTypes.length,\n processedEntityTypes: i + 1,\n currentEntityType: entityType,\n entitiesFound: totalFound,\n entitiesEmitted: totalEmitted\n }\n };\n await this.updateJobProgress(updatedJob);\n }\n\n console.log(`[ReferenceDetectionWorker] ✅ Detection complete: ${totalFound} entities found, ${totalEmitted} events emitted, ${totalErrors} errors`);\n\n // Note: JobWorker base class will create the CompleteJob with result\n // We don't set job.result here - that's handled by the base class\n }\n\n protected override async handleJobFailure(job: AnyJob, error: any): Promise<void> {\n // Call parent to handle the failure logic\n await super.handleJobFailure(job, error);\n\n // If job permanently failed, emit job.failed event\n if (job.status === 'failed' && job.metadata.type === 'detection') {\n // Type narrowing: job is FailedJob<DetectionParams>\n const detJob = job as DetectionJob;\n\n // Log the full error details to backend logs (already logged by parent)\n // Send generic error message to frontend\n await this.eventStore.appendEvent({\n type: 'job.failed',\n resourceId: detJob.params.resourceId,\n userId: detJob.metadata.userId,\n version: 1,\n payload: {\n jobId: detJob.metadata.id,\n jobType: detJob.metadata.type,\n error: 'Entity detection failed. Please try again later.',\n },\n });\n }\n }\n\n /**\n * Update job progress and emit events to Event Store\n * Overrides base class to also emit job progress events\n */\n protected override async updateJobProgress(job: AnyJob): Promise<void> {\n // Call parent to update job queue\n await super.updateJobProgress(job);\n\n // Emit events for detection jobs\n if (job.metadata.type !== 'detection') {\n return;\n }\n\n // Type guard: only running jobs have progress\n if (job.status !== 'running') {\n return;\n }\n\n const detJob = job as RunningJob<DetectionParams, DetectionProgress>;\n\n const baseEvent = {\n resourceId: detJob.params.resourceId,\n userId: detJob.metadata.userId,\n version: 1,\n };\n\n // Determine if this is the first progress update (job.started)\n const isFirstUpdate = detJob.progress.processedEntityTypes === 0;\n\n // Determine if this is the final update (job.completed)\n const isFinalUpdate =\n detJob.progress.processedEntityTypes === detJob.progress.totalEntityTypes &&\n detJob.progress.totalEntityTypes > 0;\n\n if (isFirstUpdate) {\n // First progress update - emit job.started\n await this.eventStore.appendEvent({\n type: 'job.started',\n ...baseEvent,\n payload: {\n jobId: detJob.metadata.id,\n jobType: detJob.metadata.type,\n totalSteps: detJob.params.entityTypes.length,\n },\n });\n } else if (isFinalUpdate) {\n // Final progress update - emit job.completed\n await this.eventStore.appendEvent({\n type: 'job.completed',\n ...baseEvent,\n payload: {\n jobId: detJob.metadata.id,\n jobType: detJob.metadata.type,\n foundCount: detJob.progress.entitiesFound,\n },\n });\n } else {\n // Intermediate progress - emit job.progress\n const percentage = Math.round((detJob.progress.processedEntityTypes / detJob.progress.totalEntityTypes) * 100);\n await this.eventStore.appendEvent({\n type: 'job.progress',\n ...baseEvent,\n payload: {\n jobId: detJob.metadata.id,\n jobType: detJob.metadata.type,\n percentage,\n currentStep: detJob.progress.currentEntityType,\n processedSteps: detJob.progress.processedEntityTypes,\n totalSteps: detJob.progress.totalEntityTypes,\n foundCount: detJob.progress.entitiesFound,\n },\n });\n }\n }\n}\n","import type { InferenceClient } from '@semiont/inference';\n\n/**\n * Entity reference extracted from text\n */\nexport interface ExtractedEntity {\n exact: string; // The actual text span\n entityType: string; // The detected entity type\n startOffset: number; // Character offset where entity starts\n endOffset: number; // Character offset where entity ends\n prefix?: string; // Text immediately before entity (for disambiguation)\n suffix?: string; // Text immediately after entity (for disambiguation)\n}\n\n/**\n * Extract entity references from text using AI\n *\n * @param text - The text to analyze\n * @param entityTypes - Array of entity types to detect (optionally with examples)\n * @param client - Inference client for AI operations\n * @param includeDescriptiveReferences - Include anaphoric/cataphoric references (default: false)\n * @returns Array of extracted entities with their character offsets\n */\nexport async function extractEntities(\n exact: string,\n entityTypes: string[] | { type: string; examples?: string[] }[],\n client: InferenceClient,\n includeDescriptiveReferences: boolean = false\n): Promise<ExtractedEntity[]> {\n console.log('extractEntities called with:', {\n textLength: exact.length,\n entityTypes: Array.isArray(entityTypes) ? entityTypes.map(et => typeof et === 'string' ? et : et.type) : []\n });\n\n // Format entity types for the prompt\n const entityTypesDescription = entityTypes.map(et => {\n if (typeof et === 'string') {\n return et;\n }\n return et.examples && et.examples.length > 0\n ? `${et.type} (examples: ${et.examples.slice(0, 3).join(', ')})`\n : et.type;\n }).join(', ');\n\n // Build prompt with optional support for anaphoric/cataphoric references\n // Anaphora: references that point backward (e.g., \"John arrived. He was tired.\")\n // Cataphora: references that point forward (e.g., \"When she arrived, Mary was surprised.\")\n // When enabled, include substantive descriptive references beyond simple pronouns\n const descriptiveReferenceGuidance = includeDescriptiveReferences\n ? `\nInclude both:\n- Direct mentions (names, proper nouns)\n- Descriptive references (substantive phrases that refer to entities)\n\nFor descriptive references, include:\n- Definite descriptions: \"the Nobel laureate\", \"the tech giant\", \"the former president\"\n- Role-based references: \"the CEO\", \"the physicist\", \"the author\", \"the owner\", \"the contractor\"\n- Epithets with context: \"the Cupertino-based company\", \"the iPhone maker\"\n- References to entities even when identity is unknown or unspecified\n\nDo NOT include:\n- Simple pronouns alone: he, she, it, they, him, her, them\n- Generic determiners alone: this, that, these, those\n- Possessives without substance: his, her, their, its\n\nExamples:\n- For \"Marie Curie\", include \"the Nobel laureate\" and \"the physicist\" but NOT \"she\"\n- For an unknown person, include \"the owner\" or \"the contractor\" (role-based references count even when identity is unspecified)\n`\n : `\nFind direct mentions only (names, proper nouns). Do not include pronouns or descriptive references.\n`;\n\n const prompt = `Identify entity references in the following text. Look for mentions of: ${entityTypesDescription}.\n${descriptiveReferenceGuidance}\nText to analyze:\n\"\"\"\n${exact}\n\"\"\"\n\nReturn ONLY a JSON array of entities found. Each entity should have:\n- exact: the exact text span from the input\n- entityType: one of the provided entity types\n- startOffset: character position where the entity starts (0-indexed)\n- endOffset: character position where the entity ends\n- prefix: up to 32 characters of text immediately before the entity (helps identify correct occurrence)\n- suffix: up to 32 characters of text immediately after the entity (helps identify correct occurrence)\n\nReturn empty array [] if no entities found.\nDo not include markdown formatting or code fences, just the raw JSON array.\n\nExample output:\n[{\"exact\":\"Alice\",\"entityType\":\"Person\",\"startOffset\":0,\"endOffset\":5,\"prefix\":\"\",\"suffix\":\" went to\"},{\"exact\":\"Paris\",\"entityType\":\"Location\",\"startOffset\":20,\"endOffset\":25,\"prefix\":\"went to \",\"suffix\":\" yesterday\"}]`;\n\n console.log('Sending entity extraction request');\n const response = await client.generateTextWithMetadata(\n prompt,\n 4000, // Increased to handle many entities without truncation\n 0.3 // Lower temperature for more consistent extraction\n );\n console.log('Got entity extraction response');\n\n console.log('Entity extraction raw response length:', response.text.length);\n\n try {\n // Clean up response if wrapped in markdown\n let jsonStr = response.text.trim();\n if (jsonStr.startsWith('```')) {\n jsonStr = jsonStr.replace(/^```(?:json)?\\n?/, '').replace(/\\n?```$/, '');\n }\n\n const entities = JSON.parse(jsonStr);\n console.log('Parsed', entities.length, 'entities from response');\n\n // Check if response was truncated - this is an ERROR condition\n if (response.stopReason === 'max_tokens') {\n const errorMsg = `AI response truncated: Found ${entities.length} entities but response hit max_tokens limit. Increase max_tokens or reduce resource size.`;\n console.error(`❌ ${errorMsg}`);\n throw new Error(errorMsg);\n }\n\n // Validate and fix offsets\n return entities.map((entity: any, idx: number) => {\n let startOffset = entity.startOffset;\n let endOffset = entity.endOffset;\n\n console.log(`\\n[Entity ${idx + 1}/${entities.length}]`);\n console.log(` Type: ${entity.entityType}`);\n console.log(` Text: \"${entity.exact}\"`);\n console.log(` Offsets from AI: [${startOffset}, ${endOffset}]`);\n\n // Verify the offsets are correct by checking if the text matches\n const extractedText = exact.substring(startOffset, endOffset);\n\n // If the extracted text doesn't match, find the correct position using context\n if (extractedText !== entity.exact) {\n console.log(` ⚠️ Offset mismatch!`);\n console.log(` Expected: \"${entity.exact}\"`);\n console.log(` Found at AI offsets [${startOffset}:${endOffset}]: \"${extractedText}\"`);\n\n // Show context around the AI-provided offset\n const contextStart = Math.max(0, startOffset - 50);\n const contextEnd = Math.min(exact.length, endOffset + 50);\n const contextBefore = exact.substring(contextStart, startOffset);\n const contextAfter = exact.substring(endOffset, contextEnd);\n console.log(` Context: \"...${contextBefore}[${extractedText}]${contextAfter}...\"`);\n\n console.log(` Searching for exact match in resource...`);\n\n // Try to find using prefix/suffix context if provided\n let found = false;\n if (entity.prefix || entity.suffix) {\n console.log(` Using LLM-provided context for disambiguation:`);\n if (entity.prefix) console.log(` Prefix: \"${entity.prefix}\"`);\n if (entity.suffix) console.log(` Suffix: \"${entity.suffix}\"`);\n\n // Search for all occurrences and find the one with matching context\n let searchPos = 0;\n while ((searchPos = exact.indexOf(entity.exact, searchPos)) !== -1) {\n const candidatePrefix = exact.substring(Math.max(0, searchPos - 32), searchPos);\n const candidateSuffix = exact.substring(\n searchPos + entity.exact.length,\n Math.min(exact.length, searchPos + entity.exact.length + 32)\n );\n\n // Check if context matches (allowing for partial matches at boundaries)\n const prefixMatch = !entity.prefix || candidatePrefix.endsWith(entity.prefix);\n const suffixMatch = !entity.suffix || candidateSuffix.startsWith(entity.suffix);\n\n if (prefixMatch && suffixMatch) {\n console.log(` ✅ Found match using context at offset ${searchPos} (diff: ${searchPos - startOffset})`);\n console.log(` Candidate prefix: \"${candidatePrefix}\"`);\n console.log(` Candidate suffix: \"${candidateSuffix}\"`);\n startOffset = searchPos;\n endOffset = searchPos + entity.exact.length;\n found = true;\n break;\n }\n\n searchPos++;\n }\n\n if (!found) {\n console.log(` ⚠️ No occurrence found with matching context`);\n }\n }\n\n // Fallback to first occurrence if context didn't help\n if (!found) {\n const index = exact.indexOf(entity.exact);\n if (index !== -1) {\n console.log(` ⚠️ Using first occurrence at offset ${index} (diff: ${index - startOffset})`);\n startOffset = index;\n endOffset = index + entity.exact.length;\n } else {\n console.log(` ❌ Cannot find \"${entity.exact}\" anywhere in resource`);\n console.log(` Resource starts with: \"${exact.substring(0, 200)}...\"`);\n // If we still can't find it, skip this entity\n return null;\n }\n }\n } else {\n console.log(` ✅ Offsets correct`);\n }\n\n return {\n exact: entity.exact,\n entityType: entity.entityType,\n startOffset: startOffset,\n endOffset: endOffset,\n prefix: entity.prefix,\n suffix: entity.suffix\n };\n }).filter((entity: ExtractedEntity | null): entity is ExtractedEntity => {\n // Filter out nulls and ensure we have valid offsets\n if (entity === null) {\n console.log('❌ Filtered entity: null');\n return false;\n }\n if (entity.startOffset === undefined || entity.endOffset === undefined) {\n console.log(`❌ Filtered entity \"${entity.exact}\": missing offsets`);\n return false;\n }\n if (entity.startOffset < 0) {\n console.log(`❌ Filtered entity \"${entity.exact}\": negative startOffset (${entity.startOffset})`);\n return false;\n }\n if (entity.endOffset > exact.length) {\n console.log(`❌ Filtered entity \"${entity.exact}\": endOffset (${entity.endOffset}) > text length (${exact.length})`);\n return false;\n }\n\n // Verify the text at the offsets matches\n const extractedText = exact.substring(entity.startOffset, entity.endOffset);\n if (extractedText !== entity.exact) {\n console.log(`❌ Filtered entity \"${entity.exact}\": offset mismatch`);\n console.log(` Expected: \"${entity.exact}\"`);\n console.log(` Got at [${entity.startOffset}:${entity.endOffset}]: \"${extractedText}\"`);\n return false;\n }\n\n console.log(`✅ Accepted entity \"${entity.exact}\" at [${entity.startOffset}:${entity.endOffset}]`);\n return true;\n });\n } catch (error) {\n console.error('Failed to parse entity extraction response:', error);\n return [];\n }\n}","/**\n * Generation Worker\n *\n * Processes generation jobs: runs AI inference to generate new resources\n * and emits resource.created and annotation.body.updated events.\n *\n * This worker is INDEPENDENT of HTTP clients - it just processes jobs and emits events.\n */\n\nimport { JobWorker } from '@semiont/jobs';\nimport type { AnyJob, JobQueue, RunningJob, GenerationParams, GenerationProgress } from '@semiont/jobs';\nimport { FilesystemRepresentationStore } from '@semiont/content';\nimport { ResourceContext } from '..';\nimport { generateResourceFromTopic } from '../generation/resource-generation';\nimport {\n getTargetSelector,\n getExactText,\n resourceUri,\n annotationUri,\n} from '@semiont/api-client';\nimport { getEntityTypes } from '@semiont/ontology';\nimport {\n CREATION_METHODS,\n generateUuid,\n type BodyOperation,\n resourceId,\n annotationId,\n} from '@semiont/core';\nimport { EventStore } from '@semiont/event-sourcing';\nimport type { EnvironmentConfig } from '@semiont/core';\nimport type { InferenceClient } from '@semiont/inference';\n\nexport class GenerationWorker extends JobWorker {\n constructor(\n jobQueue: JobQueue,\n private config: EnvironmentConfig,\n private eventStore: EventStore,\n private inferenceClient: InferenceClient\n ) {\n super(jobQueue);\n }\n\n protected getWorkerName(): string {\n return 'GenerationWorker';\n }\n\n protected canProcessJob(job: AnyJob): boolean {\n return job.metadata.type === 'generation';\n }\n\n protected async executeJob(job: AnyJob): Promise<void> {\n if (job.metadata.type !== 'generation') {\n throw new Error(`Invalid job type: ${job.metadata.type}`);\n }\n\n // Type guard: job must be running to execute\n if (job.status !== 'running') {\n throw new Error(`Job must be in running state to execute, got: ${job.status}`);\n }\n\n await this.processGenerationJob(job as RunningJob<GenerationParams, GenerationProgress>);\n }\n\n private async processGenerationJob(job: RunningJob<GenerationParams, GenerationProgress>): Promise<void> {\n console.log(`[GenerationWorker] Processing generation for reference ${job.params.referenceId} (job: ${job.metadata.id})`);\n\n const basePath = this.config.services.filesystem!.path;\n const projectRoot = this.config._metadata?.projectRoot;\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n\n // Update progress: fetching\n let updatedJob: RunningJob<GenerationParams, GenerationProgress> = {\n ...job,\n progress: {\n stage: 'fetching',\n percentage: 20,\n message: 'Fetching source resource...'\n }\n };\n console.log(`[GenerationWorker] 📥 ${updatedJob.progress.message}`);\n await this.updateJobProgress(updatedJob);\n\n // Fetch annotation from view storage\n // TODO: Once AnnotationContext is consolidated, use it here\n const { FilesystemViewStorage } = await import('@semiont/event-sourcing');\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n const view = await viewStorage.get(job.params.sourceResourceId);\n if (!view) {\n throw new Error(`Resource ${job.params.sourceResourceId} not found`);\n }\n const projection = view.annotations;\n\n // Construct full annotation URI for comparison\n const expectedAnnotationUri = `${this.config.services.backend!.publicURL}/annotations/${job.params.referenceId}`;\n const annotation = projection.annotations.find((a: any) =>\n a.id === expectedAnnotationUri && a.motivation === 'linking'\n );\n\n if (!annotation) {\n throw new Error(`Annotation ${job.params.referenceId} not found in resource ${job.params.sourceResourceId}`);\n }\n\n const sourceResource = await ResourceContext.getResourceMetadata(job.params.sourceResourceId, this.config);\n if (!sourceResource) {\n throw new Error(`Source resource ${job.params.sourceResourceId} not found`);\n }\n\n // Determine resource name\n const targetSelector = getTargetSelector(annotation.target);\n const resourceName = job.params.title || (targetSelector ? getExactText(targetSelector) : '') || 'New Resource';\n console.log(`[GenerationWorker] Generating resource: \"${resourceName}\"`);\n\n // Verify context is provided (required for generation)\n if (!job.params.context) {\n throw new Error('Generation context is required but was not provided in job');\n }\n console.log(`[GenerationWorker] Using pre-fetched context: ${job.params.context.sourceContext?.before?.length || 0} chars before, ${job.params.context.sourceContext?.selected?.length || 0} chars selected, ${job.params.context.sourceContext?.after?.length || 0} chars after`);\n\n // Update progress: generating (skip fetching context since it's already in job)\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'generating',\n percentage: 40,\n message: 'Creating content with AI...'\n }\n };\n console.log(`[GenerationWorker] 🤖 ${updatedJob.progress.message}`);\n await this.updateJobProgress(updatedJob);\n\n // Generate content using AI with context from job\n const prompt = job.params.prompt || `Create a comprehensive resource about \"${resourceName}\"`;\n // Extract entity types from annotation body\n const annotationEntityTypes = getEntityTypes({ body: annotation.body });\n\n const generatedContent = await generateResourceFromTopic(\n resourceName,\n job.params.entityTypes || annotationEntityTypes,\n this.inferenceClient,\n prompt,\n job.params.language,\n job.params.context, // NEW - context from job (passed from modal)\n job.params.temperature, // NEW - from job\n job.params.maxTokens // NEW - from job\n );\n\n console.log(`[GenerationWorker] ✅ Generated ${generatedContent.content.length} bytes of content`);\n\n // Update progress: creating\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'generating',\n percentage: 70,\n message: 'Content ready, creating resource...'\n }\n };\n await this.updateJobProgress(updatedJob);\n\n // Generate resource ID\n const rId = resourceId(generateUuid());\n\n // Update progress: creating\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'creating',\n percentage: 85,\n message: 'Saving resource...'\n }\n };\n console.log(`[GenerationWorker] 💾 ${updatedJob.progress.message}`);\n await this.updateJobProgress(updatedJob);\n\n // Save content to RepresentationStore\n const storedRep = await repStore.store(Buffer.from(generatedContent.content), {\n mediaType: 'text/markdown',\n rel: 'original',\n });\n console.log(`[GenerationWorker] ✅ Saved resource representation to filesystem: ${rId}`);\n\n // Emit resource.created event\n await this.eventStore.appendEvent({\n type: 'resource.created',\n resourceId: rId,\n userId: job.metadata.userId,\n version: 1,\n payload: {\n name: resourceName,\n format: 'text/markdown',\n contentChecksum: storedRep.checksum,\n creationMethod: CREATION_METHODS.GENERATED,\n entityTypes: job.params.entityTypes || annotationEntityTypes,\n language: job.params.language,\n isDraft: true,\n generatedFrom: job.params.referenceId,\n generationPrompt: undefined, // Could be added if we track the prompt\n },\n });\n console.log(`[GenerationWorker] Emitted resource.created event for ${rId}`);\n\n // Update progress: linking\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'linking',\n percentage: 95,\n message: 'Linking reference...',\n resultResourceId: rId // Store for job.completed event\n }\n };\n console.log(`[GenerationWorker] 🔗 ${updatedJob.progress.message}`);\n await this.updateJobProgress(updatedJob);\n\n // Emit annotation.body.updated event to link the annotation to the new resource\n // Build full resource URI for the annotation body\n const newResourceUri = resourceUri(`${this.config.services.backend!.publicURL}/resources/${rId}`);\n\n const operations: BodyOperation[] = [{\n op: 'add',\n item: {\n type: 'SpecificResource',\n source: newResourceUri,\n purpose: 'linking',\n },\n }];\n\n // Extract annotation ID from full URI (format: http://host/annotations/{id})\n const annotationIdSegment = job.params.referenceId.split('/').pop()!;\n\n await this.eventStore.appendEvent({\n type: 'annotation.body.updated',\n resourceId: job.params.sourceResourceId,\n userId: job.metadata.userId,\n version: 1,\n payload: {\n annotationId: annotationId(annotationIdSegment),\n operations,\n },\n });\n console.log(`[GenerationWorker] ✅ Emitted annotation.body.updated event linking ${job.params.referenceId} → ${rId}`);\n\n // Note: JobWorker base class will create the CompleteJob with result\n // We don't set job.result here - that's handled by the base class\n\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'linking',\n percentage: 100,\n message: 'Complete!',\n resultResourceId: rId // Store for job.completed event\n }\n };\n await this.updateJobProgress(updatedJob);\n\n console.log(`[GenerationWorker] ✅ Generation complete: created resource ${rId}`);\n }\n\n /**\n * Update job progress and emit events to Event Store\n * Overrides base class to also emit job progress events\n */\n protected override async updateJobProgress(job: AnyJob): Promise<void> {\n // Call parent to update job queue\n await super.updateJobProgress(job);\n\n // Emit events for generation jobs\n if (job.metadata.type !== 'generation') {\n return;\n }\n\n // Type guard: only running jobs have progress\n if (job.status !== 'running') {\n return;\n }\n\n const genJob = job as RunningJob<GenerationParams, GenerationProgress>;\n\n const baseEvent = {\n resourceId: genJob.params.sourceResourceId,\n userId: genJob.metadata.userId,\n version: 1,\n };\n\n // Emit appropriate event based on progress stage\n if (genJob.progress.stage === 'fetching' && genJob.progress.percentage === 20) {\n // First progress update - emit job.started\n await this.eventStore.appendEvent({\n type: 'job.started',\n ...baseEvent,\n payload: {\n jobId: genJob.metadata.id,\n jobType: genJob.metadata.type,\n totalSteps: 5, // fetching, generating, creating, linking, complete\n },\n });\n } else if (genJob.progress.stage === 'linking' && genJob.progress.percentage === 100) {\n // Final progress update - emit job.completed\n await this.eventStore.appendEvent({\n type: 'job.completed',\n ...baseEvent,\n payload: {\n jobId: genJob.metadata.id,\n jobType: genJob.metadata.type,\n resultResourceId: genJob.progress.resultResourceId,\n annotationUri: annotationUri(`${this.config.services.backend!.publicURL}/annotations/${genJob.params.referenceId}`),\n },\n });\n } else {\n // Intermediate progress - emit job.progress\n await this.eventStore.appendEvent({\n type: 'job.progress',\n ...baseEvent,\n payload: {\n jobId: genJob.metadata.id,\n jobType: genJob.metadata.type,\n currentStep: genJob.progress.stage,\n percentage: genJob.progress.percentage,\n message: genJob.progress.message,\n },\n });\n }\n }\n}\n","/**\n * Resource Generation Functions\n *\n * Application-specific resource generation logic including:\n * - Markdown resource generation from topics\n * - Resource summary generation\n * - Reference suggestion generation\n * - Language handling and template processing\n */\n\nimport { getLocaleEnglishName } from '@semiont/api-client';\nimport type { GenerationContext } from '@semiont/api-client';\nimport type { InferenceClient } from '@semiont/inference';\n\nfunction getLanguageName(locale: string): string {\n return getLocaleEnglishName(locale) || locale;\n}\n\n/**\n * Generate resource content using inference\n */\nexport async function generateResourceFromTopic(\n topic: string,\n entityTypes: string[],\n client: InferenceClient,\n userPrompt?: string,\n locale?: string,\n context?: GenerationContext,\n temperature?: number,\n maxTokens?: number\n): Promise<{ title: string; content: string }> {\n console.log('generateResourceFromTopic called with:', {\n topic: topic.substring(0, 100),\n entityTypes,\n hasUserPrompt: !!userPrompt,\n locale,\n hasContext: !!context,\n temperature,\n maxTokens\n });\n\n // Use provided values or defaults\n const finalTemperature = temperature ?? 0.7;\n const finalMaxTokens = maxTokens ?? 500;\n\n // Determine language instruction\n const languageInstruction = locale && locale !== 'en'\n ? `\\n\\nIMPORTANT: Write the entire resource in ${getLanguageName(locale)}.`\n : '';\n\n // Build context section if available\n let contextSection = '';\n if (context?.sourceContext) {\n const { before, selected, after } = context.sourceContext;\n contextSection = `\\n\\nSource document context:\n---\n${before ? `...${before}` : ''}\n**[${selected}]**\n${after ? `${after}...` : ''}\n---\n`;\n }\n\n // Simple, direct prompt - just ask for markdown content\n const prompt = `Generate a concise, informative resource about \"${topic}\".\n${entityTypes.length > 0 ? `Focus on these entity types: ${entityTypes.join(', ')}.` : ''}\n${userPrompt ? `Additional context: ${userPrompt}` : ''}${contextSection}${languageInstruction}\n\nRequirements:\n- Start with a clear heading (# Title)\n- Write 2-3 paragraphs of substantive content\n- Be factual and informative\n- Use markdown formatting\n- Return ONLY the markdown content, no JSON, no code fences, no additional wrapper`;\n\n // Simple parser - just use the response directly as markdown\n const parseResponse = (response: string): { title: string; content: string } => {\n // Clean up any markdown code fences if present\n let content = response.trim();\n if (content.startsWith('```markdown') || content.startsWith('```md')) {\n content = content.slice(content.indexOf('\\n') + 1);\n const endIndex = content.lastIndexOf('```');\n if (endIndex !== -1) {\n content = content.slice(0, endIndex);\n }\n } else if (content.startsWith('```')) {\n content = content.slice(3);\n const endIndex = content.lastIndexOf('```');\n if (endIndex !== -1) {\n content = content.slice(0, endIndex);\n }\n }\n\n content = content.trim();\n\n // Title is provided by the caller (topic), not extracted from generated content\n // This matches how it's actually used in generation-worker.ts line 87\n return {\n title: topic,\n content: content\n };\n };\n\n console.log('Sending prompt to inference (length:', prompt.length, 'chars)', 'temp:', finalTemperature, 'maxTokens:', finalMaxTokens);\n const response = await client.generateText(prompt, finalMaxTokens, finalTemperature);\n console.log('Got raw response (length:', response.length, 'chars)');\n\n const result = parseResponse(response);\n console.log('Parsed result:', {\n hasTitle: !!result.title,\n titleLength: result.title?.length,\n hasContent: !!result.content,\n contentLength: result.content?.length\n });\n\n return result;\n}\n\n/**\n * Generate an intelligent summary for a resource\n */\nexport async function generateResourceSummary(\n resourceName: string,\n content: string,\n entityTypes: string[],\n client: InferenceClient\n): Promise<string> {\n // Truncate content if too long\n const truncatedContent = content.length > 2000\n ? content.substring(0, 2000) + '...'\n : content;\n\n const prompt = `Create a brief, intelligent summary of this resource titled \"${resourceName}\".\n${entityTypes.length > 0 ? `Key entity types: ${entityTypes.join(', ')}` : ''}\n\nResource content:\n${truncatedContent}\n\nWrite a 2-3 sentence summary that captures the key points and would help someone understand what this resource contains.`;\n\n return await client.generateText(prompt, 150, 0.5);\n}\n\n/**\n * Generate smart suggestions for a reference\n */\nexport async function generateReferenceSuggestions(\n referenceTitle: string,\n client: InferenceClient,\n entityType?: string,\n currentContent?: string\n): Promise<string[] | null> {\n const prompt = `For a reference titled \"${referenceTitle}\"${entityType ? ` (type: ${entityType})` : ''}${currentContent ? ` with current stub: \"${currentContent}\"` : ''}, suggest 3 specific, actionable next steps or related topics to explore.\n\nFormat as a simple list, one suggestion per line.`;\n\n const response = await client.generateText(prompt, 200, 0.8);\n if (!response) {\n return null;\n }\n\n // Parse into array of suggestions\n return response\n .split('\\n')\n .map(line => line.replace(/^[-*•]\\s*/, '').trim())\n .filter(line => line.length > 0)\n .slice(0, 3);\n}\n","/**\n * Highlight Detection Worker\n *\n * Processes highlight-detection jobs: runs AI inference to find passages\n * that should be highlighted and creates highlight annotations.\n */\n\nimport { JobWorker } from '@semiont/jobs';\nimport type { AnyJob, HighlightDetectionJob, JobQueue, RunningJob, HighlightDetectionParams, HighlightDetectionProgress } from '@semiont/jobs';\nimport { ResourceContext, AnnotationDetection } from '..';\nimport { EventStore, generateAnnotationId } from '@semiont/event-sourcing';\nimport { resourceIdToURI } from '@semiont/core';\nimport type { EnvironmentConfig, ResourceId } from '@semiont/core';\nimport { userId } from '@semiont/core';\nimport type { HighlightMatch } from '../detection/motivation-parsers';\nimport type { InferenceClient } from '@semiont/inference';\n\nexport class HighlightDetectionWorker extends JobWorker {\n private isFirstProgress = true;\n\n constructor(\n jobQueue: JobQueue,\n private config: EnvironmentConfig,\n private eventStore: EventStore,\n private inferenceClient: InferenceClient\n ) {\n super(jobQueue);\n }\n\n protected getWorkerName(): string {\n return 'HighlightDetectionWorker';\n }\n\n protected canProcessJob(job: AnyJob): boolean {\n return job.metadata.type === 'highlight-detection';\n }\n\n protected async executeJob(job: AnyJob): Promise<void> {\n if (job.metadata.type !== 'highlight-detection') {\n throw new Error(`Invalid job type: ${job.metadata.type}`);\n }\n\n // Type guard: job must be running to execute\n if (job.status !== 'running') {\n throw new Error(`Job must be in running state to execute, got: ${job.status}`);\n }\n\n // Reset progress tracking\n this.isFirstProgress = true;\n await this.processHighlightDetectionJob(job as RunningJob<HighlightDetectionParams, HighlightDetectionProgress>);\n }\n\n /**\n * Override updateJobProgress to emit events to Event Store\n */\n protected override async updateJobProgress(job: AnyJob): Promise<void> {\n // Call parent to update filesystem\n await super.updateJobProgress(job);\n\n if (job.metadata.type !== 'highlight-detection') return;\n\n // Type guard: only running jobs have progress\n if (job.status !== 'running') {\n return;\n }\n\n const hlJob = job as RunningJob<HighlightDetectionParams, HighlightDetectionProgress>;\n\n const baseEvent = {\n resourceId: hlJob.params.resourceId,\n userId: hlJob.metadata.userId,\n version: 1,\n };\n\n // Determine if this is completion (100% and has result)\n const isComplete = hlJob.progress.percentage === 100;\n\n if (this.isFirstProgress) {\n // First progress update - emit job.started\n this.isFirstProgress = false;\n await this.eventStore.appendEvent({\n type: 'job.started',\n ...baseEvent,\n payload: {\n jobId: hlJob.metadata.id,\n jobType: hlJob.metadata.type,\n },\n });\n } else if (isComplete) {\n // Final update - emit job.completed\n await this.eventStore.appendEvent({\n type: 'job.completed',\n ...baseEvent,\n payload: {\n jobId: hlJob.metadata.id,\n jobType: hlJob.metadata.type,\n // Note: result would come from job.result, but that's handled by base class\n },\n });\n } else {\n // Intermediate progress - emit job.progress\n await this.eventStore.appendEvent({\n type: 'job.progress',\n ...baseEvent,\n payload: {\n jobId: hlJob.metadata.id,\n jobType: hlJob.metadata.type,\n progress: hlJob.progress,\n },\n });\n }\n }\n\n protected override async handleJobFailure(job: AnyJob, error: any): Promise<void> {\n // Call parent to handle the failure logic\n await super.handleJobFailure(job, error);\n\n // If job permanently failed, emit job.failed event\n if (job.status === 'failed' && job.metadata.type === 'highlight-detection') {\n const hlJob = job as HighlightDetectionJob;\n\n // Log the full error details to backend logs (already logged by parent)\n // Send generic error message to frontend\n await this.eventStore.appendEvent({\n type: 'job.failed',\n resourceId: hlJob.params.resourceId,\n userId: hlJob.metadata.userId,\n version: 1,\n payload: {\n jobId: hlJob.metadata.id,\n jobType: hlJob.metadata.type,\n error: 'Highlight detection failed. Please try again later.',\n },\n });\n }\n }\n\n private async processHighlightDetectionJob(job: RunningJob<HighlightDetectionParams, HighlightDetectionProgress>): Promise<void> {\n console.log(`[HighlightDetectionWorker] Processing highlight detection for resource ${job.params.resourceId} (job: ${job.metadata.id})`);\n\n // Fetch resource content\n const resource = await ResourceContext.getResourceMetadata(job.params.resourceId, this.config);\n\n if (!resource) {\n throw new Error(`Resource ${job.params.resourceId} not found`);\n }\n\n // Emit job.started and start analyzing\n let updatedJob: RunningJob<HighlightDetectionParams, HighlightDetectionProgress> = {\n ...job,\n progress: {\n stage: 'analyzing',\n percentage: 10,\n message: 'Loading resource...'\n }\n };\n await this.updateJobProgress(updatedJob);\n\n // Update progress\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'analyzing',\n percentage: 30,\n message: 'Analyzing text...'\n }\n };\n await this.updateJobProgress(updatedJob);\n\n // Use AI to detect highlights\n const highlights = await AnnotationDetection.detectHighlights(\n job.params.resourceId,\n this.config,\n this.inferenceClient,\n job.params.instructions,\n job.params.density\n );\n\n console.log(`[HighlightDetectionWorker] Found ${highlights.length} highlights to create`);\n\n // Update progress\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'creating',\n percentage: 60,\n message: `Creating ${highlights.length} annotations...`\n }\n };\n await this.updateJobProgress(updatedJob);\n\n // Create annotations for each highlight\n let created = 0;\n for (const highlight of highlights) {\n try {\n await this.createHighlightAnnotation(job.params.resourceId, job.metadata.userId, highlight);\n created++;\n } catch (error) {\n console.error(`[HighlightDetectionWorker] Failed to create highlight:`, error);\n }\n }\n\n // Note: JobWorker base class will create the CompleteJob with result\n // We don't set job.result here - that's handled by the base class\n\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'creating',\n percentage: 100,\n message: `Complete! Created ${created} highlights`\n }\n };\n\n await this.updateJobProgress(updatedJob);\n console.log(`[HighlightDetectionWorker] ✅ Created ${created}/${highlights.length} highlights`);\n }\n\n private async createHighlightAnnotation(\n resourceId: ResourceId,\n creatorUserId: string,\n highlight: HighlightMatch\n ): Promise<void> {\n const backendUrl = this.config.services.backend?.publicURL;\n if (!backendUrl) throw new Error('Backend publicURL not configured');\n\n const annotationId = generateAnnotationId(backendUrl);\n const resourceUri = resourceIdToURI(resourceId, backendUrl);\n\n // Create W3C annotation with motivation: highlighting\n // Use both TextPositionSelector and TextQuoteSelector (with prefix/suffix for fuzzy anchoring)\n const annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n 'id': annotationId,\n 'motivation': 'highlighting' as const,\n 'creator': userId(creatorUserId),\n 'created': new Date().toISOString(),\n 'target': {\n type: 'SpecificResource' as const,\n source: resourceUri,\n selector: [\n {\n type: 'TextPositionSelector' as const,\n start: highlight.start,\n end: highlight.end,\n },\n {\n type: 'TextQuoteSelector' as const,\n exact: highlight.exact,\n ...(highlight.prefix && { prefix: highlight.prefix }),\n ...(highlight.suffix && { suffix: highlight.suffix }),\n },\n ]\n },\n 'body': [] // Empty body for highlights\n };\n\n await this.eventStore.appendEvent({\n type: 'annotation.added',\n resourceId,\n userId: userId(creatorUserId),\n version: 1,\n payload: { annotation }\n });\n }\n}\n","/**\n * Assessment Detection Worker\n *\n * Processes assessment-detection jobs: runs AI inference to assess/evaluate\n * passages in the text and creates assessment annotations.\n */\n\nimport { JobWorker } from '@semiont/jobs';\nimport type { AnyJob, AssessmentDetectionJob, JobQueue, RunningJob, AssessmentDetectionParams, AssessmentDetectionProgress } from '@semiont/jobs';\nimport { ResourceContext, AnnotationDetection } from '..';\nimport { EventStore, generateAnnotationId } from '@semiont/event-sourcing';\nimport { resourceIdToURI } from '@semiont/core';\nimport type { EnvironmentConfig, ResourceId } from '@semiont/core';\nimport { userId } from '@semiont/core';\nimport type { AssessmentMatch } from '../detection/motivation-parsers';\nimport type { InferenceClient } from '@semiont/inference';\n\nexport class AssessmentDetectionWorker extends JobWorker {\n private isFirstProgress = true;\n\n constructor(\n jobQueue: JobQueue,\n private config: EnvironmentConfig,\n private eventStore: EventStore,\n private inferenceClient: InferenceClient\n ) {\n super(jobQueue);\n }\n\n protected getWorkerName(): string {\n return 'AssessmentDetectionWorker';\n }\n\n protected canProcessJob(job: AnyJob): boolean {\n return job.metadata.type === 'assessment-detection';\n }\n\n protected async executeJob(job: AnyJob): Promise<void> {\n if (job.metadata.type !== 'assessment-detection') {\n throw new Error(`Invalid job type: ${job.metadata.type}`);\n }\n\n // Type guard: job must be running to execute\n if (job.status !== 'running') {\n throw new Error(`Job must be in running state to execute, got: ${job.status}`);\n }\n\n // Reset progress tracking\n this.isFirstProgress = true;\n await this.processAssessmentDetectionJob(job as RunningJob<AssessmentDetectionParams, AssessmentDetectionProgress>);\n }\n\n /**\n * Override updateJobProgress to emit events to Event Store\n */\n protected override async updateJobProgress(job: AnyJob): Promise<void> {\n // Call parent to update filesystem\n await super.updateJobProgress(job);\n\n if (job.metadata.type !== 'assessment-detection') return;\n\n // Type guard: only running jobs have progress\n if (job.status !== 'running') {\n return;\n }\n\n const assJob = job as RunningJob<AssessmentDetectionParams, AssessmentDetectionProgress>;\n\n const baseEvent = {\n resourceId: assJob.params.resourceId,\n userId: assJob.metadata.userId,\n version: 1,\n };\n\n // Determine if this is completion (100% and has result)\n const isComplete = assJob.progress.percentage === 100;\n\n if (this.isFirstProgress) {\n // First progress update - emit job.started\n this.isFirstProgress = false;\n await this.eventStore.appendEvent({\n type: 'job.started',\n ...baseEvent,\n payload: {\n jobId: assJob.metadata.id,\n jobType: assJob.metadata.type,\n },\n });\n } else if (isComplete) {\n // Final update - emit job.completed\n await this.eventStore.appendEvent({\n type: 'job.completed',\n ...baseEvent,\n payload: {\n jobId: assJob.metadata.id,\n jobType: assJob.metadata.type,\n // Note: result would come from job.result, but that's handled by base class\n },\n });\n } else {\n // Intermediate progress - emit job.progress\n await this.eventStore.appendEvent({\n type: 'job.progress',\n ...baseEvent,\n payload: {\n jobId: assJob.metadata.id,\n jobType: assJob.metadata.type,\n progress: assJob.progress,\n },\n });\n }\n }\n\n protected override async handleJobFailure(job: AnyJob, error: any): Promise<void> {\n // Call parent to handle the failure logic\n await super.handleJobFailure(job, error);\n\n // If job permanently failed, emit job.failed event\n if (job.status === 'failed' && job.metadata.type === 'assessment-detection') {\n const aJob = job as AssessmentDetectionJob;\n\n // Log the full error details to backend logs (already logged by parent)\n // Send generic error message to frontend\n await this.eventStore.appendEvent({\n type: 'job.failed',\n resourceId: aJob.params.resourceId,\n userId: aJob.metadata.userId,\n version: 1,\n payload: {\n jobId: aJob.metadata.id,\n jobType: aJob.metadata.type,\n error: 'Assessment detection failed. Please try again later.',\n },\n });\n }\n }\n\n private async processAssessmentDetectionJob(job: RunningJob<AssessmentDetectionParams, AssessmentDetectionProgress>): Promise<void> {\n console.log(`[AssessmentDetectionWorker] Processing assessment detection for resource ${job.params.resourceId} (job: ${job.metadata.id})`);\n\n // Fetch resource content\n const resource = await ResourceContext.getResourceMetadata(job.params.resourceId, this.config);\n\n if (!resource) {\n throw new Error(`Resource ${job.params.resourceId} not found`);\n }\n\n // Emit job.started and start analyzing\n let updatedJob: RunningJob<AssessmentDetectionParams, AssessmentDetectionProgress> = {\n ...job,\n progress: {\n stage: 'analyzing',\n percentage: 10,\n message: 'Loading resource...'\n }\n };\n await this.updateJobProgress(updatedJob);\n\n // Update progress\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'analyzing',\n percentage: 30,\n message: 'Analyzing text...'\n }\n };\n await this.updateJobProgress(updatedJob);\n\n // Use AI to detect assessments\n const assessments = await AnnotationDetection.detectAssessments(\n job.params.resourceId,\n this.config,\n this.inferenceClient,\n job.params.instructions,\n job.params.tone,\n job.params.density\n );\n\n console.log(`[AssessmentDetectionWorker] Found ${assessments.length} assessments to create`);\n\n // Update progress\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'creating',\n percentage: 60,\n message: `Creating ${assessments.length} annotations...`\n }\n };\n await this.updateJobProgress(updatedJob);\n\n // Create annotations for each assessment\n let created = 0;\n for (const assessment of assessments) {\n try {\n await this.createAssessmentAnnotation(job.params.resourceId, job.metadata.userId, assessment);\n created++;\n } catch (error) {\n console.error(`[AssessmentDetectionWorker] Failed to create assessment:`, error);\n }\n }\n\n // Note: JobWorker base class will create the CompleteJob with result\n // We don't set job.result here - that's handled by the base class\n\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'creating',\n percentage: 100,\n message: `Complete! Created ${created} assessments`\n }\n };\n\n await this.updateJobProgress(updatedJob);\n console.log(`[AssessmentDetectionWorker] ✅ Created ${created}/${assessments.length} assessments`);\n }\n\n private async createAssessmentAnnotation(\n resourceId: ResourceId,\n creatorUserId: string,\n assessment: AssessmentMatch\n ): Promise<void> {\n const backendUrl = this.config.services.backend?.publicURL;\n if (!backendUrl) throw new Error('Backend publicURL not configured');\n\n const annotationId = generateAnnotationId(backendUrl);\n const resourceUri = resourceIdToURI(resourceId, backendUrl);\n\n // Create W3C annotation with motivation: assessing\n // Use both TextPositionSelector and TextQuoteSelector (with prefix/suffix for fuzzy anchoring)\n const annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n 'id': annotationId,\n 'motivation': 'assessing' as const,\n 'creator': userId(creatorUserId),\n 'created': new Date().toISOString(),\n 'target': {\n type: 'SpecificResource' as const,\n source: resourceUri,\n selector: [\n {\n type: 'TextPositionSelector' as const,\n start: assessment.start,\n end: assessment.end,\n },\n {\n type: 'TextQuoteSelector' as const,\n exact: assessment.exact,\n ...(assessment.prefix && { prefix: assessment.prefix }),\n ...(assessment.suffix && { suffix: assessment.suffix }),\n },\n ]\n },\n 'body': {\n type: 'TextualBody' as const,\n value: assessment.assessment,\n format: 'text/plain'\n }\n };\n\n await this.eventStore.appendEvent({\n type: 'annotation.added',\n resourceId,\n userId: userId(creatorUserId),\n version: 1,\n payload: { annotation }\n });\n }\n}\n","/**\n * Comment Detection Worker\n *\n * Processes comment-detection jobs: runs AI inference to identify passages\n * that would benefit from explanatory comments and creates comment annotations.\n */\n\nimport { JobWorker } from '@semiont/jobs';\nimport type { AnyJob, CommentDetectionJob, JobQueue, RunningJob, CommentDetectionParams, CommentDetectionProgress } from '@semiont/jobs';\nimport { ResourceContext, AnnotationDetection } from '..';\nimport { EventStore, generateAnnotationId } from '@semiont/event-sourcing';\nimport { resourceIdToURI } from '@semiont/core';\nimport type { EnvironmentConfig, ResourceId } from '@semiont/core';\nimport { userId } from '@semiont/core';\nimport type { CommentMatch } from '../detection/motivation-parsers';\nimport type { InferenceClient } from '@semiont/inference';\n\nexport class CommentDetectionWorker extends JobWorker {\n private isFirstProgress = true;\n\n constructor(\n jobQueue: JobQueue,\n private config: EnvironmentConfig,\n private eventStore: EventStore,\n private inferenceClient: InferenceClient\n ) {\n super(jobQueue);\n }\n\n protected getWorkerName(): string {\n return 'CommentDetectionWorker';\n }\n\n protected canProcessJob(job: AnyJob): boolean {\n return job.metadata.type === 'comment-detection';\n }\n\n protected async executeJob(job: AnyJob): Promise<void> {\n if (job.metadata.type !== 'comment-detection') {\n throw new Error(`Invalid job type: ${job.metadata.type}`);\n }\n\n // Type guard: job must be running to execute\n if (job.status !== 'running') {\n throw new Error(`Job must be in running state to execute, got: ${job.status}`);\n }\n\n // Reset progress tracking\n this.isFirstProgress = true;\n await this.processCommentDetectionJob(job as RunningJob<CommentDetectionParams, CommentDetectionProgress>);\n }\n\n /**\n * Override updateJobProgress to emit events to Event Store\n */\n protected override async updateJobProgress(job: AnyJob): Promise<void> {\n // Call parent to update filesystem\n await super.updateJobProgress(job);\n\n if (job.metadata.type !== 'comment-detection') return;\n\n // Type guard: only running jobs have progress\n if (job.status !== 'running') {\n return;\n }\n\n const cdJob = job as RunningJob<CommentDetectionParams, CommentDetectionProgress>;\n\n const baseEvent = {\n resourceId: cdJob.params.resourceId,\n userId: cdJob.metadata.userId,\n version: 1,\n };\n\n // Determine if this is completion (100% and has result)\n const isComplete = cdJob.progress.percentage === 100;\n\n if (this.isFirstProgress) {\n // First progress update - emit job.started\n this.isFirstProgress = false;\n await this.eventStore.appendEvent({\n type: 'job.started',\n ...baseEvent,\n payload: {\n jobId: cdJob.metadata.id,\n jobType: cdJob.metadata.type,\n },\n });\n } else if (isComplete) {\n // Final update - emit job.completed\n await this.eventStore.appendEvent({\n type: 'job.completed',\n ...baseEvent,\n payload: {\n jobId: cdJob.metadata.id,\n jobType: cdJob.metadata.type,\n // Note: result would come from job.result, but that's handled by base class\n },\n });\n } else {\n // Intermediate progress - emit job.progress\n await this.eventStore.appendEvent({\n type: 'job.progress',\n ...baseEvent,\n payload: {\n jobId: cdJob.metadata.id,\n jobType: cdJob.metadata.type,\n progress: cdJob.progress,\n },\n });\n }\n }\n\n protected override async handleJobFailure(job: AnyJob, error: any): Promise<void> {\n // Call parent to handle the failure logic\n await super.handleJobFailure(job, error);\n\n // If job permanently failed, emit job.failed event\n if (job.status === 'failed' && job.metadata.type === 'comment-detection') {\n const cdJob = job as CommentDetectionJob;\n\n // Log the full error details to backend logs (already logged by parent)\n // Send generic error message to frontend\n await this.eventStore.appendEvent({\n type: 'job.failed',\n resourceId: cdJob.params.resourceId,\n userId: cdJob.metadata.userId,\n version: 1,\n payload: {\n jobId: cdJob.metadata.id,\n jobType: cdJob.metadata.type,\n error: 'Comment detection failed. Please try again later.',\n },\n });\n }\n }\n\n private async processCommentDetectionJob(job: RunningJob<CommentDetectionParams, CommentDetectionProgress>): Promise<void> {\n console.log(`[CommentDetectionWorker] Processing comment detection for resource ${job.params.resourceId} (job: ${job.metadata.id})`);\n\n // Fetch resource content\n const resource = await ResourceContext.getResourceMetadata(job.params.resourceId, this.config);\n\n if (!resource) {\n throw new Error(`Resource ${job.params.resourceId} not found`);\n }\n\n // Emit job.started and start analyzing\n let updatedJob: RunningJob<CommentDetectionParams, CommentDetectionProgress> = {\n ...job,\n progress: {\n stage: 'analyzing',\n percentage: 10,\n message: 'Loading resource...'\n }\n };\n await this.updateJobProgress(updatedJob);\n\n // Update progress\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'analyzing',\n percentage: 30,\n message: 'Analyzing text and generating comments...'\n }\n };\n await this.updateJobProgress(updatedJob);\n\n // Use AI to detect passages needing comments\n const comments = await AnnotationDetection.detectComments(\n job.params.resourceId,\n this.config,\n this.inferenceClient,\n job.params.instructions,\n job.params.tone,\n job.params.density\n );\n\n console.log(`[CommentDetectionWorker] Found ${comments.length} comments to create`);\n\n // Update progress\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'creating',\n percentage: 60,\n message: `Creating ${comments.length} annotations...`\n }\n };\n await this.updateJobProgress(updatedJob);\n\n // Create annotations for each comment\n let created = 0;\n for (const comment of comments) {\n try {\n await this.createCommentAnnotation(job.params.resourceId, job.metadata.userId, comment);\n created++;\n } catch (error) {\n console.error(`[CommentDetectionWorker] Failed to create comment:`, error);\n }\n }\n\n // Note: JobWorker base class will create the CompleteJob with result\n // We don't set job.result here - that's handled by the base class\n\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'creating',\n percentage: 100,\n message: `Complete! Created ${created} comments`\n }\n };\n\n await this.updateJobProgress(updatedJob);\n console.log(`[CommentDetectionWorker] ✅ Created ${created}/${comments.length} comments`);\n }\n\n private async createCommentAnnotation(\n resourceId: ResourceId,\n userId_: string,\n comment: CommentMatch\n ): Promise<void> {\n const backendUrl = this.config.services.backend?.publicURL;\n\n if (!backendUrl) {\n throw new Error('Backend publicURL not configured');\n }\n\n const resourceUri = resourceIdToURI(resourceId, backendUrl);\n const annotationId = generateAnnotationId(backendUrl);\n\n // Create W3C-compliant annotation with motivation: \"commenting\"\n const annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n type: 'Annotation' as const,\n id: annotationId,\n motivation: 'commenting' as const,\n target: {\n type: 'SpecificResource' as const,\n source: resourceUri,\n selector: [\n {\n type: 'TextPositionSelector' as const,\n start: comment.start,\n end: comment.end\n },\n {\n type: 'TextQuoteSelector' as const,\n exact: comment.exact,\n prefix: comment.prefix || '',\n suffix: comment.suffix || ''\n }\n ]\n },\n body: [\n {\n type: 'TextualBody' as const,\n value: comment.comment,\n purpose: 'commenting' as const,\n format: 'text/plain',\n language: 'en'\n }\n ]\n };\n\n // Append annotation.added event to Event Store\n await this.eventStore.appendEvent({\n type: 'annotation.added',\n resourceId,\n userId: userId(userId_),\n version: 1,\n payload: {\n annotation\n }\n });\n\n console.log(`[CommentDetectionWorker] Created comment annotation ${annotationId} for \"${comment.exact.substring(0, 50)}...\"`);\n }\n}\n","/**\n * Tag Detection Worker\n *\n * Processes tag-detection jobs: runs AI inference to identify passages\n * serving specific structural roles (IRAC, IMRAD, Toulmin, etc.) and\n * creates tag annotations with dual-body structure.\n */\n\nimport { JobWorker } from '@semiont/jobs';\nimport type { AnyJob, TagDetectionJob, JobQueue, RunningJob, TagDetectionParams, TagDetectionProgress } from '@semiont/jobs';\nimport { ResourceContext, AnnotationDetection } from '..';\nimport { EventStore, generateAnnotationId } from '@semiont/event-sourcing';\nimport { resourceIdToURI } from '@semiont/core';\nimport { getTagSchema } from '@semiont/ontology';\nimport type { EnvironmentConfig, ResourceId } from '@semiont/core';\nimport { userId } from '@semiont/core';\nimport type { TagMatch } from '../detection/motivation-parsers';\nimport type { InferenceClient } from '@semiont/inference';\n\nexport class TagDetectionWorker extends JobWorker {\n private isFirstProgress = true;\n\n constructor(\n jobQueue: JobQueue,\n private config: EnvironmentConfig,\n private eventStore: EventStore,\n private inferenceClient: InferenceClient\n ) {\n super(jobQueue);\n }\n\n protected getWorkerName(): string {\n return 'TagDetectionWorker';\n }\n\n protected canProcessJob(job: AnyJob): boolean {\n return job.metadata.type === 'tag-detection';\n }\n\n protected async executeJob(job: AnyJob): Promise<void> {\n if (job.metadata.type !== 'tag-detection') {\n throw new Error(`Invalid job type: ${job.metadata.type}`);\n }\n\n // Type guard: job must be running to execute\n if (job.status !== 'running') {\n throw new Error(`Job must be in running state to execute, got: ${job.status}`);\n }\n\n // Reset progress tracking\n this.isFirstProgress = true;\n await this.processTagDetectionJob(job as RunningJob<TagDetectionParams, TagDetectionProgress>);\n }\n\n /**\n * Override updateJobProgress to emit events to Event Store\n */\n protected override async updateJobProgress(job: AnyJob): Promise<void> {\n // Call parent to update filesystem\n await super.updateJobProgress(job);\n\n if (job.metadata.type !== 'tag-detection') return;\n\n // Type guard: only running jobs have progress\n if (job.status !== 'running') {\n return;\n }\n\n const tdJob = job as RunningJob<TagDetectionParams, TagDetectionProgress>;\n\n const baseEvent = {\n resourceId: tdJob.params.resourceId,\n userId: tdJob.metadata.userId,\n version: 1,\n };\n\n // Determine if this is completion (100% and has result)\n const isComplete = tdJob.progress.percentage === 100;\n\n if (this.isFirstProgress) {\n // First progress update - emit job.started\n this.isFirstProgress = false;\n await this.eventStore.appendEvent({\n type: 'job.started',\n ...baseEvent,\n payload: {\n jobId: tdJob.metadata.id,\n jobType: tdJob.metadata.type,\n },\n });\n } else if (isComplete) {\n // Final update - emit job.completed\n await this.eventStore.appendEvent({\n type: 'job.completed',\n ...baseEvent,\n payload: {\n jobId: tdJob.metadata.id,\n jobType: tdJob.metadata.type,\n // Note: result would come from job.result, but that's handled by base class\n },\n });\n } else {\n // Intermediate progress - emit job.progress\n await this.eventStore.appendEvent({\n type: 'job.progress',\n ...baseEvent,\n payload: {\n jobId: tdJob.metadata.id,\n jobType: tdJob.metadata.type,\n progress: tdJob.progress,\n },\n });\n }\n }\n\n protected override async handleJobFailure(job: AnyJob, error: any): Promise<void> {\n // Call parent to handle the failure logic\n await super.handleJobFailure(job, error);\n\n // If job permanently failed, emit job.failed event\n if (job.status === 'failed' && job.metadata.type === 'tag-detection') {\n const tdJob = job as TagDetectionJob;\n\n await this.eventStore.appendEvent({\n type: 'job.failed',\n resourceId: tdJob.params.resourceId,\n userId: tdJob.metadata.userId,\n version: 1,\n payload: {\n jobId: tdJob.metadata.id,\n jobType: tdJob.metadata.type,\n error: 'Tag detection failed. Please try again later.',\n },\n });\n }\n }\n\n private async processTagDetectionJob(job: RunningJob<TagDetectionParams, TagDetectionProgress>): Promise<void> {\n console.log(`[TagDetectionWorker] Processing tag detection for resource ${job.params.resourceId} (job: ${job.metadata.id})`);\n\n // Validate schema\n const schema = getTagSchema(job.params.schemaId);\n if (!schema) {\n throw new Error(`Invalid tag schema: ${job.params.schemaId}`);\n }\n\n // Validate categories\n for (const category of job.params.categories) {\n if (!schema.tags.some(t => t.name === category)) {\n throw new Error(`Invalid category \"${category}\" for schema ${job.params.schemaId}`);\n }\n }\n\n // Fetch resource content\n const resource = await ResourceContext.getResourceMetadata(job.params.resourceId, this.config);\n if (!resource) {\n throw new Error(`Resource ${job.params.resourceId} not found`);\n }\n\n // Emit job.started\n let updatedJob: RunningJob<TagDetectionParams, TagDetectionProgress> = {\n ...job,\n progress: {\n stage: 'analyzing',\n percentage: 10,\n processedCategories: 0,\n totalCategories: job.params.categories.length,\n message: 'Loading resource...'\n }\n };\n await this.updateJobProgress(updatedJob);\n\n // Process each category separately\n const allTags: TagMatch[] = [];\n const byCategory: Record<string, number> = {};\n\n for (let i = 0; i < job.params.categories.length; i++) {\n const category = job.params.categories[i]!; // Safe: i < length check guarantees element exists\n\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'analyzing',\n percentage: 10 + Math.floor((i / job.params.categories.length) * 50),\n currentCategory: category,\n processedCategories: i + 1,\n totalCategories: job.params.categories.length,\n message: `Analyzing ${category}...`\n }\n };\n await this.updateJobProgress(updatedJob);\n\n // Detect tags for this category\n const tags = await AnnotationDetection.detectTags(\n job.params.resourceId,\n this.config,\n this.inferenceClient,\n job.params.schemaId,\n category\n );\n console.log(`[TagDetectionWorker] Found ${tags.length} tags for category \"${category}\"`);\n\n allTags.push(...tags);\n byCategory[category] = tags.length;\n }\n\n // Create annotations\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'creating',\n percentage: 60,\n processedCategories: job.params.categories.length,\n totalCategories: job.params.categories.length,\n message: `Creating ${allTags.length} tag annotations...`\n }\n };\n await this.updateJobProgress(updatedJob);\n\n let created = 0;\n for (const tag of allTags) {\n try {\n await this.createTagAnnotation(job.params.resourceId, job.metadata.userId, job.params.schemaId, tag);\n created++;\n } catch (error) {\n console.error(`[TagDetectionWorker] Failed to create tag:`, error);\n }\n }\n\n // Note: JobWorker base class will create the CompleteJob with result\n // We don't set job.result here - that's handled by the base class\n\n updatedJob = {\n ...updatedJob,\n progress: {\n stage: 'creating',\n percentage: 100,\n processedCategories: job.params.categories.length,\n totalCategories: job.params.categories.length,\n message: `Complete! Created ${created} tags`\n }\n };\n\n await this.updateJobProgress(updatedJob);\n console.log(`[TagDetectionWorker] ✅ Created ${created}/${allTags.length} tags across ${job.params.categories.length} categories`);\n }\n\n private async createTagAnnotation(\n resourceId: ResourceId,\n userId_: string,\n schemaId: string,\n tag: TagMatch\n ): Promise<void> {\n const backendUrl = this.config.services.backend?.publicURL;\n\n if (!backendUrl) {\n throw new Error('Backend publicURL not configured');\n }\n\n const resourceUri = resourceIdToURI(resourceId, backendUrl);\n const annotationId = generateAnnotationId(backendUrl);\n\n // Create W3C-compliant annotation with dual-body structure:\n // 1. purpose: \"tagging\" with category value\n // 2. purpose: \"classifying\" with schema ID\n const annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n type: 'Annotation' as const,\n id: annotationId,\n motivation: 'tagging' as const,\n target: {\n type: 'SpecificResource' as const,\n source: resourceUri,\n selector: [\n {\n type: 'TextPositionSelector' as const,\n start: tag.start,\n end: tag.end\n },\n {\n type: 'TextQuoteSelector' as const,\n exact: tag.exact,\n prefix: tag.prefix || '',\n suffix: tag.suffix || ''\n }\n ]\n },\n body: [\n {\n type: 'TextualBody' as const,\n value: tag.category,\n purpose: 'tagging' as const,\n format: 'text/plain',\n language: 'en'\n },\n {\n type: 'TextualBody' as const,\n value: schemaId,\n purpose: 'classifying' as const,\n format: 'text/plain'\n }\n ]\n };\n\n // Append annotation.added event to Event Store\n await this.eventStore.appendEvent({\n type: 'annotation.added',\n resourceId,\n userId: userId(userId_),\n version: 1,\n payload: {\n annotation\n }\n });\n\n console.log(`[TagDetectionWorker] Created tag annotation ${annotationId} for \"${tag.category}\": \"${tag.exact.substring(0, 50)}...\"`);\n }\n}\n","/**\n * GraphDB Consumer\n * Subscribes to resource events and updates GraphDB accordingly\n *\n * Makes GraphDB a projection of Event Store events (single source of truth)\n */\n\nimport { EventQuery, type EventStore } from '@semiont/event-sourcing';\nimport { didToAgent } from '@semiont/core';\nimport type { GraphDatabase } from '@semiont/graph';\nimport type { components } from '@semiont/api-client';\nimport type { ResourceEvent, StoredEvent, EnvironmentConfig, ResourceId } from '@semiont/core';\nimport { resourceId as makeResourceId, findBodyItem } from '@semiont/core';\nimport { toResourceUri, toAnnotationUri } from '@semiont/event-sourcing';\nimport { resourceUri } from '@semiont/api-client';\n\ntype Annotation = components['schemas']['Annotation'];\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\n\nexport class GraphDBConsumer {\n private subscriptions: Map<string, any> = new Map();\n private _globalSubscription: any = null; // Subscription to system-level events (kept for cleanup)\n private processing: Map<string, Promise<void>> = new Map();\n private lastProcessed: Map<string, number> = new Map();\n\n constructor(\n private config: EnvironmentConfig,\n private eventStore: EventStore,\n private graphDb: GraphDatabase\n ) {}\n\n async initialize() {\n console.log('[GraphDBConsumer] Initialized');\n // Subscribe to global system-level events\n await this.subscribeToGlobalEvents();\n }\n\n /**\n * Subscribe to global system-level events (no resourceId)\n * This allows the consumer to react to events like entitytype.added\n */\n private async subscribeToGlobalEvents() {\n this._globalSubscription = this.eventStore.bus.subscriptions.subscribeGlobal(async (storedEvent: StoredEvent) => {\n console.log(`[GraphDBConsumer] Received global event: ${storedEvent.event.type}`);\n await this.processEvent(storedEvent);\n });\n\n console.log('[GraphDBConsumer] Subscribed to global system events');\n }\n\n private ensureInitialized(): GraphDatabase {\n return this.graphDb;\n }\n\n /**\n * Subscribe to events for a resource\n * Apply each event to GraphDB\n */\n async subscribeToResource(resourceId: ResourceId) {\n this.ensureInitialized();\n\n // Convert plain ID to full URI for subscription (EventSubscriptions uses ResourceUri branded type)\n const publicURL = this.config.services.backend!.publicURL;\n const rUri = resourceUri(`${publicURL}/resources/${resourceId}`);\n\n const subscription = this.eventStore.bus.subscriptions.subscribe(rUri, async (storedEvent: StoredEvent) => {\n await this.processEvent(storedEvent);\n });\n\n this.subscriptions.set(resourceId, subscription);\n console.log(`[GraphDBConsumer] Subscribed to ${resourceId}`);\n }\n\n /**\n * Stop the consumer and unsubscribe from all events\n */\n async stop() {\n console.log('[GraphDBConsumer] Stopping...');\n\n // Unsubscribe from all resource subscriptions\n for (const subscription of this.subscriptions.values()) {\n if (subscription && typeof subscription.unsubscribe === 'function') {\n subscription.unsubscribe();\n }\n }\n this.subscriptions.clear();\n\n // Unsubscribe from global subscription\n if (this._globalSubscription && typeof this._globalSubscription.unsubscribe === 'function') {\n this._globalSubscription.unsubscribe();\n }\n this._globalSubscription = null;\n\n console.log('[GraphDBConsumer] Stopped');\n }\n\n /**\n * Process event with ordering guarantee (sequential per resource)\n */\n protected async processEvent(storedEvent: StoredEvent): Promise<void> {\n const { resourceId } = storedEvent.event;\n\n // ⚠️ BRITTLE: System-level events (entitytype.added) have no resourceId\n // Process these immediately without ordering guarantees\n if (!resourceId) {\n await this.applyEventToGraph(storedEvent);\n return;\n }\n\n // Wait for previous event on this resource to complete\n const previousProcessing = this.processing.get(resourceId);\n if (previousProcessing) {\n await previousProcessing;\n }\n\n // Create new processing promise\n const processingPromise = this.applyEventToGraph(storedEvent);\n this.processing.set(resourceId, processingPromise);\n\n try {\n await processingPromise;\n this.lastProcessed.set(resourceId, storedEvent.metadata.sequenceNumber);\n } catch (error) {\n console.error(`[GraphDBConsumer] Failed to process event:`, error);\n throw error;\n } finally {\n this.processing.delete(resourceId);\n }\n }\n\n /**\n * Apply event to GraphDB\n */\n protected async applyEventToGraph(storedEvent: StoredEvent): Promise<void> {\n const graphDb = this.ensureInitialized();\n const event = storedEvent.event;\n\n console.log(`[GraphDBConsumer] Applying ${event.type} to GraphDB (seq=${storedEvent.metadata.sequenceNumber})`);\n\n switch (event.type) {\n case 'resource.created': {\n if (!event.resourceId) throw new Error('resource.created requires resourceId');\n const resourceUri = toResourceUri({ baseUrl: this.config.services.backend!.publicURL }, event.resourceId);\n const resource: ResourceDescriptor = {\n '@context': 'https://schema.org/',\n '@id': resourceUri,\n name: event.payload.name,\n entityTypes: event.payload.entityTypes || [],\n representations: [{\n mediaType: event.payload.format,\n checksum: event.payload.contentChecksum,\n rel: 'original',\n }],\n archived: false,\n dateCreated: new Date().toISOString(),\n wasAttributedTo: didToAgent(event.userId),\n creationMethod: 'api',\n };\n console.log(`[GraphDBConsumer] Creating resource in graph: ${resourceUri}`);\n await graphDb.createResource(resource);\n console.log(`[GraphDBConsumer] ✅ Resource created in graph: ${resourceUri}`);\n break;\n }\n\n case 'resource.cloned': {\n if (!event.resourceId) throw new Error('resource.cloned requires resourceId');\n const resourceUri = toResourceUri({ baseUrl: this.config.services.backend!.publicURL }, event.resourceId);\n const resource: ResourceDescriptor = {\n '@context': 'https://schema.org/',\n '@id': resourceUri,\n name: event.payload.name,\n entityTypes: event.payload.entityTypes || [],\n representations: [{\n mediaType: event.payload.format,\n checksum: event.payload.contentChecksum,\n rel: 'original',\n }],\n archived: false,\n dateCreated: new Date().toISOString(),\n wasAttributedTo: didToAgent(event.userId),\n creationMethod: 'clone',\n };\n console.log(`[GraphDBConsumer] Creating cloned resource in graph: ${resourceUri}`);\n await graphDb.createResource(resource);\n console.log(`[GraphDBConsumer] ✅ Cloned resource created in graph: ${resourceUri}`);\n break;\n }\n\n case 'resource.archived':\n if (!event.resourceId) throw new Error('resource.archived requires resourceId');\n await graphDb.updateResource(toResourceUri({ baseUrl: this.config.services.backend!.publicURL }, event.resourceId), {\n archived: true,\n });\n break;\n\n case 'resource.unarchived':\n if (!event.resourceId) throw new Error('resource.unarchived requires resourceId');\n await graphDb.updateResource(toResourceUri({ baseUrl: this.config.services.backend!.publicURL }, event.resourceId), {\n archived: false,\n });\n break;\n\n case 'annotation.added':\n console.log(`[GraphDBConsumer] 🔍 ENTERED annotation.added case block`);\n console.log(`[GraphDBConsumer] Annotation ID: ${event.payload.annotation.id}`);\n // Event payload contains Omit<Annotation, 'creator' | 'created'>\n // Add creator from event metadata (created not needed for graph)\n await graphDb.createAnnotation({\n ...event.payload.annotation,\n creator: didToAgent(event.userId),\n });\n console.log(`[GraphDBConsumer] ✅ Annotation created in graph: ${event.payload.annotation.id}`);\n break;\n\n case 'annotation.removed':\n await graphDb.deleteAnnotation(toAnnotationUri({ baseUrl: this.config.services.backend!.publicURL }, event.payload.annotationId));\n break;\n\n case 'annotation.body.updated':\n console.log(`[GraphDBConsumer] 🔍 ENTERED annotation.body.updated case block`);\n console.log(`[GraphDBConsumer] Event payload:`, JSON.stringify(event.payload));\n // Apply fine-grained body operations\n try {\n console.log(`[GraphDBConsumer] Creating annotation URI for: ${event.payload.annotationId}`);\n const annotationUri = toAnnotationUri({ baseUrl: this.config.services.backend!.publicURL }, event.payload.annotationId);\n console.log(`[GraphDBConsumer] ✅ Annotation URI created: ${annotationUri}`);\n console.log(`[GraphDBConsumer] Processing annotation.body.updated for ${annotationUri}`);\n console.log(`[GraphDBConsumer] Operations:`, JSON.stringify(event.payload.operations));\n\n // Get current annotation from graph\n const currentAnnotation = await graphDb.getAnnotation(annotationUri);\n console.log(`[GraphDBConsumer] Current annotation in graph:`, currentAnnotation ? 'FOUND' : 'NOT FOUND');\n\n if (currentAnnotation) {\n console.log(`[GraphDBConsumer] Current body:`, JSON.stringify(currentAnnotation.body));\n\n // Ensure body is an array\n let bodyArray = Array.isArray(currentAnnotation.body)\n ? [...currentAnnotation.body]\n : currentAnnotation.body\n ? [currentAnnotation.body]\n : [];\n\n // Apply each operation\n for (const op of event.payload.operations) {\n console.log(`[GraphDBConsumer] Applying operation:`, JSON.stringify(op));\n if (op.op === 'add') {\n // Add item (idempotent - don't add if already exists)\n const exists = findBodyItem(bodyArray, op.item) !== -1;\n if (!exists) {\n bodyArray.push(op.item);\n console.log(`[GraphDBConsumer] Added item to body`);\n } else {\n console.log(`[GraphDBConsumer] Item already exists, skipping`);\n }\n } else if (op.op === 'remove') {\n // Remove item\n const index = findBodyItem(bodyArray, op.item);\n if (index !== -1) {\n bodyArray.splice(index, 1);\n console.log(`[GraphDBConsumer] Removed item from body`);\n }\n } else if (op.op === 'replace') {\n // Replace item\n const index = findBodyItem(bodyArray, op.oldItem);\n if (index !== -1) {\n bodyArray[index] = op.newItem;\n console.log(`[GraphDBConsumer] Replaced item in body`);\n }\n }\n }\n\n console.log(`[GraphDBConsumer] New body array:`, JSON.stringify(bodyArray));\n console.log(`[GraphDBConsumer] Calling updateAnnotation...`);\n\n // Update annotation with new body\n await graphDb.updateAnnotation(annotationUri, {\n body: bodyArray,\n } as Partial<Annotation>);\n\n console.log(`[GraphDBConsumer] ✅ updateAnnotation completed successfully`);\n } else {\n console.log(`[GraphDBConsumer] ⚠️ Annotation not found in graph, skipping update`);\n }\n } catch (error) {\n // If annotation doesn't exist in graph (e.g., created before consumer started),\n // log warning but don't fail - event store is source of truth\n console.error(`[GraphDBConsumer] ❌ ERROR in annotation.body.updated handler`);\n console.error(`[GraphDBConsumer] Annotation ID: ${event.payload.annotationId}`);\n console.error(`[GraphDBConsumer] Error:`, error);\n console.error(`[GraphDBConsumer] Error stack:`, error instanceof Error ? error.stack : 'N/A');\n }\n break;\n\n case 'entitytag.added':\n if (!event.resourceId) throw new Error('entitytag.added requires resourceId');\n const doc = await graphDb.getResource(toResourceUri({ baseUrl: this.config.services.backend!.publicURL }, event.resourceId));\n if (doc) {\n await graphDb.updateResource(toResourceUri({ baseUrl: this.config.services.backend!.publicURL }, event.resourceId), {\n entityTypes: [...(doc.entityTypes || []), event.payload.entityType],\n });\n }\n break;\n\n case 'entitytag.removed':\n if (!event.resourceId) throw new Error('entitytag.removed requires resourceId');\n const doc2 = await graphDb.getResource(toResourceUri({ baseUrl: this.config.services.backend!.publicURL }, event.resourceId));\n if (doc2) {\n await graphDb.updateResource(toResourceUri({ baseUrl: this.config.services.backend!.publicURL }, event.resourceId), {\n entityTypes: (doc2.entityTypes || []).filter(t => t !== event.payload.entityType),\n });\n }\n break;\n\n case 'entitytype.added':\n // ⚠️ BRITTLE: Event routing depends on absence of resourceId\n // This handler is called for system-level events (global entity type collection)\n // TODO: Design cleaner event routing with explicit projection targets\n await graphDb.addEntityType(event.payload.entityType);\n break;\n\n default:\n console.warn(`[GraphDBConsumer] Unknown event type: ${(event as ResourceEvent).type}`);\n }\n }\n\n /**\n * Rebuild entire resource from events\n * Useful for recovery or initial sync\n */\n async rebuildResource(resourceId: ResourceId): Promise<void> {\n const graphDb = this.ensureInitialized();\n console.log(`[GraphDBConsumer] Rebuilding resource ${resourceId} from events`);\n\n // Delete existing data\n try {\n await graphDb.deleteResource(toResourceUri({ baseUrl: this.config.services.backend!.publicURL }, makeResourceId(resourceId)));\n } catch (error) {\n // Resource might not exist yet\n console.log(`[GraphDBConsumer] No existing resource to delete: ${resourceId}`);\n }\n\n // Replay all events\n const query = new EventQuery(this.eventStore.log.storage);\n const events = await query.getResourceEvents(resourceId);\n\n for (const storedEvent of events) {\n await this.applyEventToGraph(storedEvent);\n }\n\n console.log(`[GraphDBConsumer] Rebuilt ${resourceId} from ${events.length} events`);\n }\n\n /**\n * Rebuild entire GraphDB from all events\n * Uses two-pass approach to ensure all resources exist before creating REFERENCES edges\n */\n async rebuildAll(): Promise<void> {\n const graphDb = this.ensureInitialized();\n console.log('[GraphDBConsumer] Rebuilding entire GraphDB from events...');\n console.log('[GraphDBConsumer] Using two-pass approach: nodes first, then edges\\n');\n\n // Clear database\n await graphDb.clearDatabase();\n\n // Get all resource IDs by scanning event shards\n const query = new EventQuery(this.eventStore.log.storage);\n const allResourceIds = await this.eventStore.log.getAllResourceIds();\n\n console.log(`[GraphDBConsumer] Found ${allResourceIds.length} resources to rebuild`);\n\n // PASS 1: Create all nodes (resources and annotations)\n // Skip annotation.body.updated events to avoid creating REFERENCES edges\n console.log('\\n[GraphDBConsumer] === PASS 1: Creating all nodes (resources + annotations) ===');\n for (const resourceId of allResourceIds) {\n const events = await query.getResourceEvents(makeResourceId(resourceId as string));\n\n for (const storedEvent of events) {\n // Skip annotation.body.updated - we'll process these in pass 2\n if (storedEvent.event.type === 'annotation.body.updated') {\n continue;\n }\n await this.applyEventToGraph(storedEvent);\n }\n }\n console.log('[GraphDBConsumer] ✅ Pass 1 complete - all nodes created\\n');\n\n // PASS 2: Create all edges (REFERENCES relationships)\n // Process ONLY annotation.body.updated events\n console.log('[GraphDBConsumer] === PASS 2: Creating all REFERENCES edges ===');\n for (const resourceId of allResourceIds) {\n const events = await query.getResourceEvents(makeResourceId(resourceId as string));\n\n for (const storedEvent of events) {\n // Process ONLY annotation.body.updated events\n if (storedEvent.event.type === 'annotation.body.updated') {\n await this.applyEventToGraph(storedEvent);\n }\n }\n }\n console.log('[GraphDBConsumer] ✅ Pass 2 complete - all edges created\\n');\n\n console.log('[GraphDBConsumer] Rebuild complete');\n }\n\n /**\n * Get consumer health metrics\n */\n getHealthMetrics(): {\n subscriptions: number;\n lastProcessed: Record<string, number>;\n processing: string[];\n } {\n return {\n subscriptions: this.subscriptions.size,\n lastProcessed: Object.fromEntries(this.lastProcessed),\n processing: Array.from(this.processing.keys()),\n };\n }\n\n /**\n * Unsubscribe from resource\n */\n async unsubscribeFromResource(resourceId: ResourceId): Promise<void> {\n const subscription = this.subscriptions.get(resourceId);\n if (subscription) {\n subscription.unsubscribe();\n this.subscriptions.delete(resourceId);\n console.log(`[GraphDBConsumer] Unsubscribed from ${resourceId}`);\n }\n }\n\n /**\n * Unsubscribe from all resources\n */\n async unsubscribeAll(): Promise<void> {\n for (const [_resourceId, subscription] of this.subscriptions) {\n subscription.unsubscribe();\n }\n this.subscriptions.clear();\n console.log('[GraphDBConsumer] Unsubscribed from all resources');\n }\n\n /**\n * Shutdown consumer\n */\n async shutdown(): Promise<void> {\n await this.unsubscribeAll();\n\n // Unsubscribe from global events\n if (this._globalSubscription) {\n this._globalSubscription.unsubscribe();\n this._globalSubscription = null;\n console.log('[GraphDBConsumer] Unsubscribed from global events');\n }\n\n // GraphDB disconnect is handled by MakeMeaningService.stop()\n console.log('[GraphDBConsumer] Shut down');\n }\n}","/**\n * Resource Context\n *\n * Assembles resource context from view storage and content store\n * Does NOT touch the graph - graph queries go through GraphContext\n */\n\nimport { FilesystemViewStorage } from '@semiont/event-sourcing';\nimport { FilesystemRepresentationStore } from '@semiont/content';\nimport { getPrimaryRepresentation, decodeRepresentation } from '@semiont/api-client';\nimport type { components } from '@semiont/api-client';\nimport type { EnvironmentConfig, ResourceId } from '@semiont/core';\n\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\n\nexport interface ListResourcesFilters {\n search?: string;\n archived?: boolean;\n}\n\nexport class ResourceContext {\n /**\n * Get resource metadata from view storage\n */\n static async getResourceMetadata(resourceId: ResourceId, config: EnvironmentConfig): Promise<ResourceDescriptor | null> {\n const basePath = config.services.filesystem!.path;\n const projectRoot = config._metadata?.projectRoot;\n\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n\n const view = await viewStorage.get(resourceId);\n if (!view) {\n return null;\n }\n\n return view.resource;\n }\n\n /**\n * List all resources by scanning view storage\n */\n static async listResources(filters: ListResourcesFilters | undefined, config: EnvironmentConfig): Promise<ResourceDescriptor[]> {\n const basePath = config.services.filesystem!.path;\n const projectRoot = config._metadata?.projectRoot;\n\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n\n const allViews = await viewStorage.getAll();\n const resources: ResourceDescriptor[] = [];\n\n for (const view of allViews) {\n const doc = view.resource;\n\n // Apply filters\n if (filters?.archived !== undefined && doc.archived !== filters.archived) {\n continue;\n }\n\n if (filters?.search) {\n const searchLower = filters.search.toLowerCase();\n if (!doc.name.toLowerCase().includes(searchLower)) {\n continue;\n }\n }\n\n resources.push(doc);\n }\n\n // Sort by creation date (newest first)\n resources.sort((a, b) => {\n const aTime = a.dateCreated ? new Date(a.dateCreated).getTime() : 0;\n const bTime = b.dateCreated ? new Date(b.dateCreated).getTime() : 0;\n return bTime - aTime;\n });\n\n return resources;\n }\n\n /**\n * Add content previews to resources (for search results)\n * Retrieves and decodes the first 200 characters of each resource's primary representation\n */\n static async addContentPreviews(\n resources: ResourceDescriptor[],\n config: EnvironmentConfig\n ): Promise<Array<ResourceDescriptor & { content: string }>> {\n const basePath = config.services.filesystem!.path;\n const projectRoot = config._metadata?.projectRoot;\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n\n return await Promise.all(\n resources.map(async (doc) => {\n try {\n const primaryRep = getPrimaryRepresentation(doc);\n if (primaryRep?.checksum && primaryRep?.mediaType) {\n const contentBuffer = await repStore.retrieve(primaryRep.checksum, primaryRep.mediaType);\n const contentPreview = decodeRepresentation(contentBuffer, primaryRep.mediaType).slice(0, 200);\n return { ...doc, content: contentPreview };\n }\n return { ...doc, content: '' };\n } catch {\n return { ...doc, content: '' };\n }\n })\n );\n }\n}\n","/**\n * Annotation Context\n *\n * Assembles annotation context from view storage and content store.\n * Provides methods for:\n * - Getting resource annotations\n * - Building LLM context for annotations\n * - Extracting annotation text context\n * - Generating AI summaries\n */\n\nimport { getInferenceClient } from '@semiont/inference';\nimport { generateResourceSummary } from './generation/resource-generation';\nimport {\n getBodySource,\n getTargetSource,\n getTargetSelector,\n getResourceEntityTypes,\n getTextPositionSelector,\n getPrimaryRepresentation,\n decodeRepresentation,\n} from '@semiont/api-client';\nimport type { components, AnnotationUri, GenerationContext } from '@semiont/api-client';\nimport { FilesystemRepresentationStore } from '@semiont/content';\nimport { FilesystemViewStorage } from '@semiont/event-sourcing';\nimport type {\n EnvironmentConfig,\n ResourceId,\n ResourceAnnotations,\n AnnotationId,\n AnnotationCategory,\n} from '@semiont/core';\nimport { resourceId as createResourceId, uriToResourceId } from '@semiont/core';\nimport { getEntityTypes } from '@semiont/ontology';\nimport { ResourceContext } from './resource-context';\n\ntype AnnotationLLMContextResponse = components['schemas']['AnnotationLLMContextResponse'];\ntype TextPositionSelector = components['schemas']['TextPositionSelector'];\ntype TextQuoteSelector = components['schemas']['TextQuoteSelector'];\ntype Annotation = components['schemas']['Annotation'];\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\ntype AnnotationContextResponse = components['schemas']['AnnotationContextResponse'];\ntype ContextualSummaryResponse = components['schemas']['ContextualSummaryResponse'];\n\nexport interface BuildContextOptions {\n includeSourceContext?: boolean;\n includeTargetContext?: boolean;\n contextWindow?: number;\n}\n\ninterface AnnotationTextContext {\n before: string;\n selected: string;\n after: string;\n}\n\nexport class AnnotationContext {\n /**\n * Build LLM context for an annotation\n *\n * @param annotationUri - Full annotation URI (e.g., http://localhost:4000/annotations/abc123)\n * @param resourceId - Source resource ID\n * @param config - Application configuration\n * @param options - Context building options\n * @returns Rich context for LLM processing\n * @throws Error if annotation or resource not found\n */\n static async buildLLMContext(\n annotationUri: AnnotationUri,\n resourceId: ResourceId,\n config: EnvironmentConfig,\n options: BuildContextOptions = {}\n ): Promise<AnnotationLLMContextResponse> {\n const {\n includeSourceContext = true,\n includeTargetContext = true,\n contextWindow = 1000\n } = options;\n\n // Validate contextWindow range\n if (contextWindow < 100 || contextWindow > 5000) {\n throw new Error('contextWindow must be between 100 and 5000');\n }\n\n console.log(`[AnnotationContext] buildLLMContext called with annotationUri=${annotationUri}, resourceId=${resourceId}`);\n\n const basePath = config.services.filesystem!.path;\n console.log(`[AnnotationContext] basePath=${basePath}`);\n\n const projectRoot = config._metadata?.projectRoot;\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n\n // Get source resource view\n console.log(`[AnnotationContext] Getting view for resourceId=${resourceId}`);\n let sourceView;\n try {\n sourceView = await viewStorage.get(resourceId);\n console.log(`[AnnotationContext] Got view:`, !!sourceView);\n\n if (!sourceView) {\n throw new Error('Source resource not found');\n }\n } catch (error) {\n console.error(`[AnnotationContext] Error getting view:`, error);\n throw error;\n }\n\n console.log(`[AnnotationContext] Looking for annotation ${annotationUri} in resource ${resourceId}`);\n console.log(`[AnnotationContext] View has ${sourceView.annotations.annotations.length} annotations`);\n console.log(`[AnnotationContext] First 5 annotation IDs:`, sourceView.annotations.annotations.slice(0, 5).map((a: Annotation) => a.id));\n\n // Find the annotation in the view (annotations have full URIs as their id)\n const annotation = sourceView.annotations.annotations.find((a: Annotation) => a.id === annotationUri);\n console.log(`[AnnotationContext] Found annotation:`, !!annotation);\n\n if (!annotation) {\n throw new Error('Annotation not found in view');\n }\n\n const targetSource = getTargetSource(annotation.target);\n // Extract resource ID from the target source URI (format: http://host/resources/{id})\n const targetResourceId = targetSource.split('/').pop();\n console.log(`[AnnotationContext] Target source: ${targetSource}, Expected resource ID: ${resourceId}, Extracted ID: ${targetResourceId}`);\n\n if (targetResourceId !== resourceId) {\n throw new Error(`Annotation target resource ID (${targetResourceId}) does not match expected resource ID (${resourceId})`);\n }\n\n const sourceDoc = sourceView.resource;\n\n // Get target resource if annotation is a reference (has resolved body source)\n const bodySource = getBodySource(annotation.body);\n\n // Extract target document from body source URI if present\n let targetDoc = null;\n if (bodySource) {\n // Inline extraction: \"http://localhost:4000/resources/abc123\" → \"abc123\"\n const parts = (bodySource as string).split('/');\n const lastPart = parts[parts.length - 1];\n if (!lastPart) {\n throw new Error(`Invalid body source URI: ${bodySource}`);\n }\n const targetResourceId = createResourceId(lastPart);\n const targetView = await viewStorage.get(targetResourceId);\n targetDoc = targetView?.resource || null;\n }\n\n // Build source context if requested\n let sourceContext;\n if (includeSourceContext) {\n const primaryRep = getPrimaryRepresentation(sourceDoc);\n if (!primaryRep?.checksum || !primaryRep?.mediaType) {\n throw new Error('Source content not found');\n }\n const sourceContent = await repStore.retrieve(primaryRep.checksum, primaryRep.mediaType);\n const contentStr = decodeRepresentation(sourceContent, primaryRep.mediaType);\n\n const targetSelectorRaw = getTargetSelector(annotation.target);\n\n // Handle array of selectors - take the first one\n const targetSelector = Array.isArray(targetSelectorRaw) ? targetSelectorRaw[0] : targetSelectorRaw;\n\n console.log(`[AnnotationContext] Target selector type:`, targetSelector?.type);\n\n if (!targetSelector) {\n console.warn(`[AnnotationContext] No target selector found`);\n } else if (targetSelector.type === 'TextPositionSelector') {\n // TypeScript now knows this is TextPositionSelector with required start/end\n const selector = targetSelector as TextPositionSelector;\n const start = selector.start;\n const end = selector.end;\n\n const before = contentStr.slice(Math.max(0, start - contextWindow), start);\n const selected = contentStr.slice(start, end);\n const after = contentStr.slice(end, Math.min(contentStr.length, end + contextWindow));\n\n sourceContext = { before, selected, after };\n console.log(`[AnnotationContext] Built source context using TextPositionSelector (${start}-${end})`);\n } else if (targetSelector.type === 'TextQuoteSelector') {\n // TypeScript now knows this is TextQuoteSelector with required exact\n const selector = targetSelector as TextQuoteSelector;\n const exact = selector.exact;\n const index = contentStr.indexOf(exact);\n\n if (index !== -1) {\n const start = index;\n const end = index + exact.length;\n\n const before = contentStr.slice(Math.max(0, start - contextWindow), start);\n const selected = exact;\n const after = contentStr.slice(end, Math.min(contentStr.length, end + contextWindow));\n\n sourceContext = { before, selected, after };\n console.log(`[AnnotationContext] Built source context using TextQuoteSelector (found at ${index})`);\n } else {\n console.warn(`[AnnotationContext] TextQuoteSelector exact text not found in content: \"${exact.substring(0, 50)}...\"`);\n }\n } else {\n console.warn(`[AnnotationContext] Unknown selector type: ${(targetSelector as any).type}`);\n }\n }\n\n // Build target context if requested and available\n let targetContext;\n if (includeTargetContext && targetDoc) {\n const targetRep = getPrimaryRepresentation(targetDoc);\n if (targetRep?.checksum && targetRep?.mediaType) {\n const targetContent = await repStore.retrieve(targetRep.checksum, targetRep.mediaType);\n const contentStr = decodeRepresentation(targetContent, targetRep.mediaType);\n\n // Create inference client for this request (HTTP handler context)\n const client = await getInferenceClient(config);\n\n targetContext = {\n content: contentStr.slice(0, contextWindow * 2),\n summary: await generateResourceSummary(targetDoc.name, contentStr, getResourceEntityTypes(targetDoc), client),\n };\n }\n }\n\n // TODO: Generate suggested resolution using AI\n const suggestedResolution = undefined;\n\n // Build GenerationContext structure\n const generationContext: GenerationContext | undefined = sourceContext ? {\n sourceContext: {\n before: sourceContext.before || '',\n selected: sourceContext.selected,\n after: sourceContext.after || '',\n },\n metadata: {\n resourceType: 'document',\n language: sourceDoc.language as string | undefined,\n entityTypes: getEntityTypes(annotation),\n },\n } : undefined;\n\n const response: AnnotationLLMContextResponse = {\n annotation,\n sourceResource: sourceDoc,\n targetResource: targetDoc,\n ...(generationContext ? { context: generationContext } : {}),\n ...(sourceContext ? { sourceContext } : {}), // Keep for backward compatibility\n ...(targetContext ? { targetContext } : {}),\n ...(suggestedResolution ? { suggestedResolution } : {}),\n };\n\n return response;\n }\n\n /**\n * Get resource annotations from view storage (fast path)\n * Throws if view missing\n */\n static async getResourceAnnotations(resourceId: ResourceId, config: EnvironmentConfig): Promise<ResourceAnnotations> {\n if (!config.services?.filesystem?.path) {\n throw new Error('Filesystem path not found in configuration');\n }\n const basePath = config.services.filesystem.path;\n const projectRoot = config._metadata?.projectRoot;\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n const view = await viewStorage.get(resourceId);\n\n if (!view) {\n throw new Error(`Resource ${resourceId} not found in view storage`);\n }\n\n return view.annotations;\n }\n\n /**\n * Get all annotations\n * @returns Array of all annotation objects\n */\n static async getAllAnnotations(resourceId: ResourceId, config: EnvironmentConfig): Promise<Annotation[]> {\n const annotations = await this.getResourceAnnotations(resourceId, config);\n\n // Enrich resolved references with document names\n // NOTE: Future optimization - make this optional via query param if performance becomes an issue\n return await this.enrichResolvedReferences(annotations.annotations, config);\n }\n\n /**\n * Enrich reference annotations with resolved document names\n * Adds _resolvedDocumentName property to annotations that link to documents\n * @private\n */\n private static async enrichResolvedReferences(annotations: Annotation[], config: EnvironmentConfig): Promise<Annotation[]> {\n if (!config.services?.filesystem?.path) {\n return annotations;\n }\n\n // Extract unique resolved document URIs from reference annotations\n const resolvedUris = new Set<string>();\n for (const ann of annotations) {\n if (ann.motivation === 'linking' && ann.body) {\n const body = Array.isArray(ann.body) ? ann.body : [ann.body];\n for (const item of body) {\n if (item.type === 'SpecificResource' && item.purpose === 'linking' && item.source) {\n resolvedUris.add(item.source);\n }\n }\n }\n }\n\n if (resolvedUris.size === 0) {\n return annotations;\n }\n\n // Batch fetch all resolved documents in parallel\n const basePath = config.services.filesystem.path;\n const projectRoot = config._metadata?.projectRoot;\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n\n const metadataPromises = Array.from(resolvedUris).map(async (uri) => {\n const docId = uri.split('/resources/')[1];\n if (!docId) return null;\n\n try {\n const view = await viewStorage.get(docId as ResourceId);\n if (view?.resource?.name) {\n return {\n uri,\n metadata: {\n name: view.resource.name,\n mediaType: view.resource.mediaType as string | undefined\n }\n };\n }\n } catch (e) {\n // Document might not exist, skip\n }\n return null;\n });\n\n const results = await Promise.all(metadataPromises);\n const uriToMetadata = new Map<string, { name: string; mediaType?: string }>();\n for (const result of results) {\n if (result) {\n uriToMetadata.set(result.uri, result.metadata);\n }\n }\n\n // Add _resolvedDocumentName and _resolvedDocumentMediaType to annotations\n return annotations.map(ann => {\n if (ann.motivation === 'linking' && ann.body) {\n const body = Array.isArray(ann.body) ? ann.body : [ann.body];\n for (const item of body) {\n if (item.type === 'SpecificResource' && item.purpose === 'linking' && item.source) {\n const metadata = uriToMetadata.get(item.source);\n if (metadata) {\n return {\n ...ann,\n _resolvedDocumentName: metadata.name,\n _resolvedDocumentMediaType: metadata.mediaType\n } as Annotation;\n }\n }\n }\n }\n return ann;\n });\n }\n\n /**\n * Get resource stats (version info)\n * @returns Version and timestamp info for the annotations\n */\n static async getResourceStats(resourceId: ResourceId, config: EnvironmentConfig): Promise<{\n resourceId: ResourceId;\n version: number;\n updatedAt: string;\n }> {\n const annotations = await this.getResourceAnnotations(resourceId, config);\n return {\n resourceId: annotations.resourceId,\n version: annotations.version,\n updatedAt: annotations.updatedAt,\n };\n }\n\n /**\n * Check if resource exists in view storage\n */\n static async resourceExists(resourceId: ResourceId, config: EnvironmentConfig): Promise<boolean> {\n if (!config.services?.filesystem?.path) {\n throw new Error('Filesystem path not found in configuration');\n }\n const basePath = config.services.filesystem.path;\n const projectRoot = config._metadata?.projectRoot;\n const viewStorage = new FilesystemViewStorage(basePath, projectRoot);\n return await viewStorage.exists(resourceId);\n }\n\n /**\n * Get a single annotation by ID\n * O(1) lookup using resource ID to access view storage\n */\n static async getAnnotation(annotationId: AnnotationId, resourceId: ResourceId, config: EnvironmentConfig): Promise<Annotation | null> {\n const annotations = await this.getResourceAnnotations(resourceId, config);\n // Extract short ID from annotation's full URI for comparison\n return annotations.annotations.find((a: Annotation) => {\n const shortId = a.id.split('/').pop();\n return shortId === annotationId;\n }) || null;\n }\n\n /**\n * List annotations with optional filtering\n * @param filters - Optional filters like resourceId and type\n * @throws Error if resourceId not provided (cross-resource queries not supported in view storage)\n */\n static async listAnnotations(filters: { resourceId?: ResourceId; type?: AnnotationCategory } | undefined, config: EnvironmentConfig): Promise<Annotation[]> {\n if (!filters?.resourceId) {\n throw new Error('resourceId is required for annotation listing - cross-resource queries not supported in view storage');\n }\n\n // Use view storage directly\n return await this.getAllAnnotations(filters.resourceId, config);\n }\n\n /**\n * Get annotation context (selected text with surrounding context)\n */\n static async getAnnotationContext(\n annotationId: AnnotationId,\n resourceId: ResourceId,\n contextBefore: number,\n contextAfter: number,\n config: EnvironmentConfig\n ): Promise<AnnotationContextResponse> {\n const basePath = config.services.filesystem!.path;\n const projectRoot = config._metadata?.projectRoot;\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n\n // Get annotation from view storage\n const annotation = await this.getAnnotation(annotationId, resourceId, config);\n if (!annotation) {\n throw new Error('Annotation not found');\n }\n\n // Get resource metadata from view storage\n const resource = await ResourceContext.getResourceMetadata(\n uriToResourceId(getTargetSource(annotation.target)),\n config\n );\n if (!resource) {\n throw new Error('Resource not found');\n }\n\n // Get content from representation store\n const contentStr = await this.getResourceContent(resource, repStore);\n\n // Extract context based on annotation position\n const context = this.extractAnnotationContext(annotation, contentStr, contextBefore, contextAfter);\n\n return {\n annotation: annotation,\n context,\n resource: {\n '@context': resource['@context'],\n '@id': resource['@id'],\n name: resource.name,\n entityTypes: resource.entityTypes,\n representations: resource.representations,\n archived: resource.archived,\n creationMethod: resource.creationMethod,\n wasAttributedTo: resource.wasAttributedTo,\n dateCreated: resource.dateCreated,\n },\n };\n }\n\n /**\n * Generate AI summary of annotation in context\n */\n static async generateAnnotationSummary(\n annotationId: AnnotationId,\n resourceId: ResourceId,\n config: EnvironmentConfig\n ): Promise<ContextualSummaryResponse> {\n const basePath = config.services.filesystem!.path;\n const projectRoot = config._metadata?.projectRoot;\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n\n // Get annotation from view storage\n const annotation = await this.getAnnotation(annotationId, resourceId, config);\n if (!annotation) {\n throw new Error('Annotation not found');\n }\n\n // Get resource from view storage\n const resource = await ResourceContext.getResourceMetadata(\n uriToResourceId(getTargetSource(annotation.target)),\n config\n );\n if (!resource) {\n throw new Error('Resource not found');\n }\n\n // Get content from representation store\n const contentStr = await this.getResourceContent(resource, repStore);\n\n // Extract annotation text with context (fixed 500 chars for summary)\n const contextSize = 500;\n const context = this.extractAnnotationContext(annotation, contentStr, contextSize, contextSize);\n\n // Extract entity types from annotation body\n const annotationEntityTypes = getEntityTypes(annotation);\n\n // Generate summary using LLM\n const summary = await this.generateSummary(resource, context, annotationEntityTypes, config);\n\n return {\n summary,\n relevantFields: {\n resourceId: resource.id,\n resourceName: resource.name,\n entityTypes: annotationEntityTypes,\n },\n context: {\n before: context.before.substring(Math.max(0, context.before.length - 200)), // Last 200 chars\n selected: context.selected,\n after: context.after.substring(0, 200), // First 200 chars\n },\n };\n }\n\n /**\n * Get resource content as string\n */\n private static async getResourceContent(\n resource: ResourceDescriptor,\n repStore: FilesystemRepresentationStore\n ): Promise<string> {\n const primaryRep = getPrimaryRepresentation(resource);\n if (!primaryRep?.checksum || !primaryRep?.mediaType) {\n throw new Error('Resource content not found');\n }\n const content = await repStore.retrieve(primaryRep.checksum, primaryRep.mediaType);\n return decodeRepresentation(content, primaryRep.mediaType);\n }\n\n /**\n * Extract annotation context from resource content\n */\n private static extractAnnotationContext(\n annotation: Annotation,\n contentStr: string,\n contextBefore: number,\n contextAfter: number\n ): AnnotationTextContext {\n const targetSelector = getTargetSelector(annotation.target);\n const posSelector = targetSelector ? getTextPositionSelector(targetSelector) : null;\n if (!posSelector) {\n throw new Error('TextPositionSelector required for context');\n }\n\n const selStart = posSelector.start;\n const selEnd = posSelector.end;\n const start = Math.max(0, selStart - contextBefore);\n const end = Math.min(contentStr.length, selEnd + contextAfter);\n\n return {\n before: contentStr.substring(start, selStart),\n selected: contentStr.substring(selStart, selEnd),\n after: contentStr.substring(selEnd, end),\n };\n }\n\n /**\n * Generate LLM summary of annotation in context\n * Creates inference client per-request (HTTP handler context)\n */\n private static async generateSummary(\n resource: ResourceDescriptor,\n context: AnnotationTextContext,\n entityTypes: string[],\n config: EnvironmentConfig\n ): Promise<string> {\n const summaryPrompt = `Summarize this text in context:\n\nContext before: \"${context.before.substring(Math.max(0, context.before.length - 200))}\"\nSelected exact: \"${context.selected}\"\nContext after: \"${context.after.substring(0, 200)}\"\n\nResource: ${resource.name}\nEntity types: ${entityTypes.join(', ')}`;\n\n // Create client for this HTTP request\n const client = await getInferenceClient(config);\n return await client.generateText(summaryPrompt, 500, 0.5);\n }\n}\n","/**\n * Graph Context\n *\n * Provides graph database operations for resources and annotations.\n * All methods require graph traversal - must use graph database.\n */\n\nimport { getGraphDatabase } from '@semiont/graph';\nimport { resourceIdToURI } from '@semiont/core';\nimport type {\n ResourceId,\n EnvironmentConfig,\n GraphConnection,\n GraphPath,\n} from '@semiont/core';\nimport type { components } from '@semiont/api-client';\n\ntype Annotation = components['schemas']['Annotation'];\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\n\nexport class GraphContext {\n /**\n * Get all resources referencing this resource (backlinks)\n * Requires graph traversal - must use graph database\n */\n static async getBacklinks(resourceId: ResourceId, config: EnvironmentConfig): Promise<Annotation[]> {\n const graphDb = await getGraphDatabase(config);\n const resourceUri = resourceIdToURI(resourceId, config.services.backend!.publicURL);\n return await graphDb.getResourceReferencedBy(resourceUri);\n }\n\n /**\n * Find shortest path between two resources\n * Requires graph traversal - must use graph database\n */\n static async findPath(\n fromResourceId: ResourceId,\n toResourceId: ResourceId,\n config: EnvironmentConfig,\n maxDepth?: number\n ): Promise<GraphPath[]> {\n const graphDb = await getGraphDatabase(config);\n return await graphDb.findPath(fromResourceId, toResourceId, maxDepth);\n }\n\n /**\n * Get resource connections (graph edges)\n * Requires graph traversal - must use graph database\n */\n static async getResourceConnections(resourceId: ResourceId, config: EnvironmentConfig): Promise<GraphConnection[]> {\n const graphDb = await getGraphDatabase(config);\n return await graphDb.getResourceConnections(resourceId);\n }\n\n /**\n * Search resources by name (cross-resource query)\n * Requires full-text search - must use graph database\n */\n static async searchResources(query: string, config: EnvironmentConfig, limit?: number): Promise<ResourceDescriptor[]> {\n const graphDb = await getGraphDatabase(config);\n return await graphDb.searchResources(query, limit);\n }\n}\n","/**\n * Annotation Detection\n *\n * Orchestrates the full annotation detection pipeline:\n * 1. Fetch resource metadata and content\n * 2. Build AI prompts using MotivationPrompts\n * 3. Call AI inference\n * 4. Parse and validate results using MotivationParsers\n *\n * This is the high-level API for AI-powered annotation detection.\n * Workers and other consumers should use these methods instead of\n * implementing detection logic directly.\n */\n\nimport { ResourceContext } from './resource-context';\nimport { FilesystemRepresentationStore } from '@semiont/content';\nimport { getPrimaryRepresentation, decodeRepresentation } from '@semiont/api-client';\nimport type { InferenceClient } from '@semiont/inference';\nimport { MotivationPrompts } from './detection/motivation-prompts';\nimport {\n MotivationParsers,\n type CommentMatch,\n type HighlightMatch,\n type AssessmentMatch,\n type TagMatch,\n} from './detection/motivation-parsers';\nimport { getTagSchema, getSchemaCategory } from '@semiont/ontology';\nimport type { EnvironmentConfig, ResourceId } from '@semiont/core';\n\nexport class AnnotationDetection {\n /**\n * Detect comments in a resource\n *\n * @param resourceId - The resource to analyze\n * @param config - Environment configuration\n * @param client - Inference client for AI operations\n * @param instructions - Optional user instructions for comment generation\n * @param tone - Optional tone guidance (e.g., \"academic\", \"conversational\")\n * @param density - Optional target number of comments per 2000 words\n * @returns Array of validated comment matches\n */\n static async detectComments(\n resourceId: ResourceId,\n config: EnvironmentConfig,\n client: InferenceClient,\n instructions?: string,\n tone?: string,\n density?: number\n ): Promise<CommentMatch[]> {\n // 1. Fetch resource metadata\n const resource = await ResourceContext.getResourceMetadata(resourceId, config);\n if (!resource) {\n throw new Error(`Resource ${resourceId} not found`);\n }\n\n // 2. Load content from representation store\n const content = await this.loadResourceContent(resourceId, config);\n if (!content) {\n throw new Error(`Could not load content for resource ${resourceId}`);\n }\n\n // 3. Build prompt\n const prompt = MotivationPrompts.buildCommentPrompt(content, instructions, tone, density);\n\n // 4. Call AI inference\n const response = await client.generateText(\n prompt,\n 3000, // maxTokens: Higher than highlights/assessments due to comment text\n 0.4 // temperature: Slightly higher to allow creative context\n );\n\n // 5. Parse and validate response\n return MotivationParsers.parseComments(response, content);\n }\n\n /**\n * Detect highlights in a resource\n *\n * @param resourceId - The resource to analyze\n * @param config - Environment configuration\n * @param client - Inference client for AI operations\n * @param instructions - Optional user instructions for highlight selection\n * @param density - Optional target number of highlights per 2000 words\n * @returns Array of validated highlight matches\n */\n static async detectHighlights(\n resourceId: ResourceId,\n config: EnvironmentConfig,\n client: InferenceClient,\n instructions?: string,\n density?: number\n ): Promise<HighlightMatch[]> {\n // 1. Fetch resource metadata\n const resource = await ResourceContext.getResourceMetadata(resourceId, config);\n if (!resource) {\n throw new Error(`Resource ${resourceId} not found`);\n }\n\n // 2. Load content from representation store\n const content = await this.loadResourceContent(resourceId, config);\n if (!content) {\n throw new Error(`Could not load content for resource ${resourceId}`);\n }\n\n // 3. Build prompt\n const prompt = MotivationPrompts.buildHighlightPrompt(content, instructions, density);\n\n // 4. Call AI inference\n const response = await client.generateText(\n prompt,\n 2000, // maxTokens: Lower than comments/assessments (no body text)\n 0.3 // temperature: Low for consistent importance judgments\n );\n\n // 5. Parse and validate response\n return MotivationParsers.parseHighlights(response, content);\n }\n\n /**\n * Detect assessments in a resource\n *\n * @param resourceId - The resource to analyze\n * @param config - Environment configuration\n * @param client - Inference client for AI operations\n * @param instructions - Optional user instructions for assessment generation\n * @param tone - Optional tone guidance (e.g., \"critical\", \"supportive\")\n * @param density - Optional target number of assessments per 2000 words\n * @returns Array of validated assessment matches\n */\n static async detectAssessments(\n resourceId: ResourceId,\n config: EnvironmentConfig,\n client: InferenceClient,\n instructions?: string,\n tone?: string,\n density?: number\n ): Promise<AssessmentMatch[]> {\n // 1. Fetch resource metadata\n const resource = await ResourceContext.getResourceMetadata(resourceId, config);\n if (!resource) {\n throw new Error(`Resource ${resourceId} not found`);\n }\n\n // 2. Load content from representation store\n const content = await this.loadResourceContent(resourceId, config);\n if (!content) {\n throw new Error(`Could not load content for resource ${resourceId}`);\n }\n\n // 3. Build prompt\n const prompt = MotivationPrompts.buildAssessmentPrompt(content, instructions, tone, density);\n\n // 4. Call AI inference\n const response = await client.generateText(\n prompt,\n 3000, // maxTokens: Higher for assessment text\n 0.3 // temperature: Lower for analytical consistency\n );\n\n // 5. Parse and validate response\n return MotivationParsers.parseAssessments(response, content);\n }\n\n /**\n * Detect tags in a resource for a specific category\n *\n * @param resourceId - The resource to analyze\n * @param config - Environment configuration\n * @param client - Inference client for AI operations\n * @param schemaId - The tag schema identifier (e.g., \"irac\", \"imrad\")\n * @param category - The specific category to detect\n * @returns Array of validated tag matches\n */\n static async detectTags(\n resourceId: ResourceId,\n config: EnvironmentConfig,\n client: InferenceClient,\n schemaId: string,\n category: string\n ): Promise<TagMatch[]> {\n // Validate schema and category\n const schema = getTagSchema(schemaId);\n if (!schema) {\n throw new Error(`Invalid tag schema: ${schemaId}`);\n }\n\n const categoryInfo = getSchemaCategory(schemaId, category);\n if (!categoryInfo) {\n throw new Error(`Invalid category \"${category}\" for schema ${schemaId}`);\n }\n\n // 1. Fetch resource metadata\n const resource = await ResourceContext.getResourceMetadata(resourceId, config);\n if (!resource) {\n throw new Error(`Resource ${resourceId} not found`);\n }\n\n // 2. Load content from representation store (FULL content for structural analysis)\n const content = await this.loadResourceContent(resourceId, config);\n if (!content) {\n throw new Error(`Could not load content for resource ${resourceId}`);\n }\n\n // 3. Build prompt with schema and category information\n const prompt = MotivationPrompts.buildTagPrompt(\n content,\n category,\n schema.name,\n schema.description,\n schema.domain,\n categoryInfo.description,\n categoryInfo.examples\n );\n\n // 4. Call AI inference\n const response = await client.generateText(\n prompt,\n 4000, // maxTokens: Higher for full document analysis\n 0.2 // temperature: Lower for structural consistency\n );\n\n // 5. Parse response (without validation)\n const parsedTags = MotivationParsers.parseTags(response);\n\n // 6. Validate offsets and add category\n return MotivationParsers.validateTagOffsets(parsedTags, content, category);\n }\n\n /**\n * Load resource content from representation store\n * Helper method used by all detection methods\n *\n * @param resourceId - The resource ID to load\n * @param config - Environment configuration\n * @returns Resource content as string, or null if not available\n */\n private static async loadResourceContent(\n resourceId: ResourceId,\n config: EnvironmentConfig\n ): Promise<string | null> {\n const resource = await ResourceContext.getResourceMetadata(resourceId, config);\n if (!resource) return null;\n\n const primaryRep = getPrimaryRepresentation(resource);\n if (!primaryRep) return null;\n\n // Only process text content\n const baseMediaType = primaryRep.mediaType?.split(';')[0]?.trim() || '';\n if (baseMediaType !== 'text/plain' && baseMediaType !== 'text/markdown') {\n return null;\n }\n\n if (!primaryRep.checksum || !primaryRep.mediaType) return null;\n\n const basePath = config.services.filesystem!.path;\n const projectRoot = config._metadata?.projectRoot;\n const repStore = new FilesystemRepresentationStore({ basePath }, projectRoot);\n const contentBuffer = await repStore.retrieve(primaryRep.checksum, primaryRep.mediaType);\n return decodeRepresentation(contentBuffer, primaryRep.mediaType);\n }\n}\n","/**\n * Prompt builders for annotation detection motivations\n *\n * Provides static methods to build AI prompts for each Web Annotation motivation type.\n * Extracted from worker implementations to centralize prompt logic.\n */\n\nexport class MotivationPrompts {\n /**\n * Build a prompt for detecting comment-worthy passages\n *\n * @param content - The text content to analyze (will be truncated to 8000 chars)\n * @param instructions - Optional user-provided instructions\n * @param tone - Optional tone guidance (e.g., \"academic\", \"conversational\")\n * @param density - Optional target number of comments per 2000 words\n * @returns Formatted prompt string\n */\n static buildCommentPrompt(\n content: string,\n instructions?: string,\n tone?: string,\n density?: number\n ): string {\n let prompt: string;\n\n if (instructions) {\n // User provided specific instructions - minimal prompt, let instructions drive behavior\n const toneGuidance = tone ? ` Use a ${tone} tone.` : '';\n const densityGuidance = density\n ? `\\n\\nAim for approximately ${density} comments per 2000 words of text.`\n : ''; // Let user instructions determine density\n\n prompt = `Add comments to passages in this text following these instructions:\n\n${instructions}${toneGuidance}${densityGuidance}\n\nText to analyze:\n---\n${content.substring(0, 8000)}\n---\n\nReturn a JSON array of comments. Each comment must have:\n- \"exact\": the exact text passage being commented on (quoted verbatim from source)\n- \"start\": character offset where the passage starts\n- \"end\": character offset where the passage ends\n- \"prefix\": up to 32 characters of text immediately before the passage\n- \"suffix\": up to 32 characters of text immediately after the passage\n- \"comment\": your comment following the instructions above\n\nReturn ONLY a valid JSON array, no additional text or explanation.\n\nExample:\n[\n {\"exact\": \"the quarterly review meeting\", \"start\": 142, \"end\": 169, \"prefix\": \"We need to schedule \", \"suffix\": \" for next month.\", \"comment\": \"Who will lead this? Should we invite the external auditors?\"}\n]`;\n } else {\n // No specific instructions - fall back to explanatory/educational mode\n const toneGuidance = tone\n ? `\\n\\nTone: Use a ${tone} style in your comments.`\n : '';\n const densityGuidance = density\n ? `\\n- Aim for approximately ${density} comments per 2000 words`\n : `\\n- Aim for 3-8 comments per 2000 words (not too sparse or dense)`;\n\n prompt = `Identify passages in this text that would benefit from explanatory comments.\nFor each passage, provide contextual information, clarification, or background.${toneGuidance}\n\nGuidelines:\n- Select passages that reference technical terms, historical figures, complex concepts, or unclear references\n- Provide comments that ADD VALUE beyond restating the text\n- Focus on explanation, background, or connections to other ideas\n- Avoid obvious or trivial comments\n- Keep comments concise (1-3 sentences typically)${densityGuidance}\n\nText to analyze:\n---\n${content.substring(0, 8000)}\n---\n\nReturn a JSON array of comments. Each comment should have:\n- \"exact\": the exact text passage being commented on (quoted verbatim from source)\n- \"start\": character offset where the passage starts\n- \"end\": character offset where the passage ends\n- \"prefix\": up to 32 characters of text immediately before the passage\n- \"suffix\": up to 32 characters of text immediately after the passage\n- \"comment\": your explanatory comment (1-3 sentences, provide context/background/clarification)\n\nReturn ONLY a valid JSON array, no additional text or explanation.\n\nExample format:\n[\n {\"exact\": \"Ouranos\", \"start\": 52, \"end\": 59, \"prefix\": \"In the beginning, \", \"suffix\": \" ruled the universe\", \"comment\": \"Ouranos (also spelled Uranus) is the primordial Greek deity personifying the sky. In Hesiod's Theogony, he is the son and husband of Gaia (Earth) and father of the Titans.\"}\n]`;\n }\n\n return prompt;\n }\n\n /**\n * Build a prompt for detecting highlight-worthy passages\n *\n * @param content - The text content to analyze (will be truncated to 8000 chars)\n * @param instructions - Optional user-provided instructions\n * @param density - Optional target number of highlights per 2000 words\n * @returns Formatted prompt string\n */\n static buildHighlightPrompt(\n content: string,\n instructions?: string,\n density?: number\n ): string {\n let prompt: string;\n\n if (instructions) {\n // User provided specific instructions - minimal prompt, let instructions drive behavior\n const densityGuidance = density\n ? `\\n\\nAim for approximately ${density} highlights per 2000 words of text.`\n : ''; // Let user instructions determine density\n\n prompt = `Identify passages in this text to highlight following these instructions:\n\n${instructions}${densityGuidance}\n\nText to analyze:\n---\n${content.substring(0, 8000)}\n---\n\nReturn a JSON array of highlights. Each highlight must have:\n- \"exact\": the exact text passage to highlight (quoted verbatim from source)\n- \"start\": character offset where the passage starts\n- \"end\": character offset where the passage ends\n- \"prefix\": up to 32 characters of text immediately before the passage\n- \"suffix\": up to 32 characters of text immediately after the passage\n\nReturn ONLY a valid JSON array, no additional text or explanation.\n\nExample:\n[\n {\"exact\": \"revenue grew 45% year-over-year\", \"start\": 142, \"end\": 174, \"prefix\": \"In Q3 2024, \", \"suffix\": \", exceeding all forecasts.\"}\n]`;\n } else {\n // No specific instructions - fall back to importance/salience mode\n const densityGuidance = density\n ? `\\n- Aim for approximately ${density} highlights per 2000 words`\n : `\\n- Aim for 3-8 highlights per 2000 words (be selective)`;\n\n prompt = `Identify passages in this text that merit highlighting for their importance or salience.\nFocus on content that readers should notice and remember.\n\nGuidelines:\n- Highlight key claims, findings, or conclusions\n- Highlight important definitions, terminology, or concepts\n- Highlight notable quotes or particularly striking statements\n- Highlight critical decisions, action items, or turning points\n- Select passages that are SIGNIFICANT, not just interesting\n- Avoid trivial or obvious content${densityGuidance}\n\nText to analyze:\n---\n${content.substring(0, 8000)}\n---\n\nReturn a JSON array of highlights. Each highlight should have:\n- \"exact\": the exact text passage to highlight (quoted verbatim from source)\n- \"start\": character offset where the passage starts\n- \"end\": character offset where the passage ends\n- \"prefix\": up to 32 characters of text immediately before the passage\n- \"suffix\": up to 32 characters of text immediately after the passage\n\nReturn ONLY a valid JSON array, no additional text or explanation.\n\nExample format:\n[\n {\"exact\": \"we will discontinue support for legacy systems by March 2025\", \"start\": 52, \"end\": 113, \"prefix\": \"After careful consideration, \", \"suffix\": \". This decision affects\"}\n]`;\n }\n\n return prompt;\n }\n\n /**\n * Build a prompt for detecting assessment-worthy passages\n *\n * @param content - The text content to analyze (will be truncated to 8000 chars)\n * @param instructions - Optional user-provided instructions\n * @param tone - Optional tone guidance (e.g., \"critical\", \"supportive\")\n * @param density - Optional target number of assessments per 2000 words\n * @returns Formatted prompt string\n */\n static buildAssessmentPrompt(\n content: string,\n instructions?: string,\n tone?: string,\n density?: number\n ): string {\n let prompt: string;\n\n if (instructions) {\n // User provided specific instructions - minimal prompt, let instructions drive behavior\n const toneGuidance = tone ? ` Use a ${tone} tone.` : '';\n const densityGuidance = density\n ? `\\n\\nAim for approximately ${density} assessments per 2000 words of text.`\n : ''; // Let user instructions determine density\n\n prompt = `Assess passages in this text following these instructions:\n\n${instructions}${toneGuidance}${densityGuidance}\n\nText to analyze:\n---\n${content.substring(0, 8000)}\n---\n\nReturn a JSON array of assessments. Each assessment must have:\n- \"exact\": the exact text passage being assessed (quoted verbatim from source)\n- \"start\": character offset where the passage starts\n- \"end\": character offset where the passage ends\n- \"prefix\": up to 32 characters of text immediately before the passage\n- \"suffix\": up to 32 characters of text immediately after the passage\n- \"assessment\": your assessment following the instructions above\n\nReturn ONLY a valid JSON array, no additional text or explanation.\n\nExample:\n[\n {\"exact\": \"the quarterly revenue target\", \"start\": 142, \"end\": 169, \"prefix\": \"We established \", \"suffix\": \" for Q4 2024.\", \"assessment\": \"This target seems ambitious given market conditions. Consider revising based on recent trends.\"}\n]`;\n } else {\n // No specific instructions - fall back to analytical/evaluation mode\n const toneGuidance = tone\n ? `\\n\\nTone: Use a ${tone} style in your assessments.`\n : '';\n const densityGuidance = density\n ? `\\n- Aim for approximately ${density} assessments per 2000 words`\n : `\\n- Aim for 2-6 assessments per 2000 words (focus on key passages)`;\n\n prompt = `Identify passages in this text that merit critical assessment or evaluation.\nFor each passage, provide analysis of its validity, strength, or implications.${toneGuidance}\n\nGuidelines:\n- Select passages containing claims, arguments, conclusions, or assertions\n- Assess evidence quality, logical soundness, or practical implications\n- Provide assessments that ADD INSIGHT beyond restating the text\n- Focus on passages where evaluation would help readers form judgments\n- Keep assessments concise yet substantive (1-3 sentences typically)${densityGuidance}\n\nText to analyze:\n---\n${content.substring(0, 8000)}\n---\n\nReturn a JSON array of assessments. Each assessment should have:\n- \"exact\": the exact text passage being assessed (quoted verbatim from source)\n- \"start\": character offset where the passage starts\n- \"end\": character offset where the passage ends\n- \"prefix\": up to 32 characters of text immediately before the passage\n- \"suffix\": up to 32 characters of text immediately after the passage\n- \"assessment\": your analytical assessment (1-3 sentences, evaluate validity/strength/implications)\n\nReturn ONLY a valid JSON array, no additional text or explanation.\n\nExample format:\n[\n {\"exact\": \"AI will replace most jobs by 2030\", \"start\": 52, \"end\": 89, \"prefix\": \"Many experts predict that \", \"suffix\": \", fundamentally reshaping\", \"assessment\": \"This claim lacks nuance and supporting evidence. Employment patterns historically show job transformation rather than wholesale replacement. The timeline appears speculative without specific sector analysis.\"}\n]`;\n }\n\n return prompt;\n }\n\n /**\n * Build a prompt for detecting structural tags\n *\n * @param content - The full text content to analyze (NOT truncated for structural analysis)\n * @param category - The specific category to detect\n * @param schemaName - Human-readable schema name\n * @param schemaDescription - Schema description\n * @param schemaDomain - Schema domain\n * @param categoryDescription - Category description\n * @param categoryExamples - Example questions/guidance for this category\n * @returns Formatted prompt string\n */\n static buildTagPrompt(\n content: string,\n category: string,\n schemaName: string,\n schemaDescription: string,\n schemaDomain: string,\n categoryDescription: string,\n categoryExamples: string[]\n ): string {\n // Build prompt with schema context and category-specific guidance\n const prompt = `You are analyzing a text using the ${schemaName} framework.\n\nSchema: ${schemaDescription}\nDomain: ${schemaDomain}\n\nYour task: Identify passages that serve the structural role of \"${category}\".\n\nCategory: ${category}\nDescription: ${categoryDescription}\nKey questions:\n${categoryExamples.map(ex => `- ${ex}`).join('\\n')}\n\nGuidelines:\n- Focus on STRUCTURAL FUNCTION, not semantic content\n- A passage serves the \"${category}\" role if it performs this function in the document's structure\n- Look for passages that explicitly fulfill this role\n- Passages can be sentences, paragraphs, or sections\n- Aim for precision - only tag passages that clearly serve this structural role\n- Typical documents have 1-5 instances of each category (some may have 0)\n\nText to analyze:\n---\n${content}\n---\n\nReturn a JSON array of tags. Each tag should have:\n- \"exact\": the exact text passage (quoted verbatim from source)\n- \"start\": character offset where the passage starts\n- \"end\": character offset where the passage ends\n- \"prefix\": up to 32 characters of text immediately before the passage\n- \"suffix\": up to 32 characters of text immediately after the passage\n\nReturn ONLY a valid JSON array, no additional text or explanation.\n\nExample format:\n[\n {\"exact\": \"What duty did the defendant owe?\", \"start\": 142, \"end\": 175, \"prefix\": \"The central question is: \", \"suffix\": \" This question must be\"},\n {\"exact\": \"In tort law, a duty of care is established when...\", \"start\": 412, \"end\": 520, \"prefix\": \"Legal framework:\\\\n\", \"suffix\": \"\\\\n\\\\nApplying this standard\"}\n]`;\n\n return prompt;\n }\n}\n","/**\n * Response parsers for annotation detection motivations\n *\n * Provides static methods to parse and validate AI responses for each motivation type.\n * Includes offset validation and correction logic.\n * Extracted from worker implementations to centralize parsing logic.\n */\n\nimport { validateAndCorrectOffsets } from '@semiont/api-client';\n\n/**\n * Represents a detected comment with validated position\n */\nexport interface CommentMatch {\n exact: string;\n start: number;\n end: number;\n prefix?: string;\n suffix?: string;\n comment: string;\n}\n\n/**\n * Represents a detected highlight with validated position\n */\nexport interface HighlightMatch {\n exact: string;\n start: number;\n end: number;\n prefix?: string;\n suffix?: string;\n}\n\n/**\n * Represents a detected assessment with validated position\n */\nexport interface AssessmentMatch {\n exact: string;\n start: number;\n end: number;\n prefix?: string;\n suffix?: string;\n assessment: string;\n}\n\n/**\n * Represents a detected tag with validated position\n */\nexport interface TagMatch {\n exact: string;\n start: number;\n end: number;\n prefix?: string;\n suffix?: string;\n category: string;\n}\n\nexport class MotivationParsers {\n /**\n * Parse and validate AI response for comment detection\n *\n * @param response - Raw AI response string (may include markdown code fences)\n * @param content - Original content to validate offsets against\n * @returns Array of validated comment matches\n */\n static parseComments(response: string, content: string): CommentMatch[] {\n try {\n // Clean up markdown code fences if present\n let cleaned = response.trim();\n if (cleaned.startsWith('```')) {\n cleaned = cleaned.replace(/^```(?:json)?\\n?/, '').replace(/\\n?```$/, '');\n }\n\n const parsed = JSON.parse(cleaned);\n\n if (!Array.isArray(parsed)) {\n console.warn('[MotivationParsers] Comment response is not an array');\n return [];\n }\n\n // Validate and filter\n const valid = parsed.filter((c: any) =>\n c &&\n typeof c.exact === 'string' &&\n typeof c.start === 'number' &&\n typeof c.end === 'number' &&\n typeof c.comment === 'string' &&\n c.comment.trim().length > 0\n );\n\n console.log(`[MotivationParsers] Parsed ${valid.length} valid comments from ${parsed.length} total`);\n\n // Validate and correct AI's offsets, then extract proper context\n // AI sometimes returns offsets that don't match the actual text position\n const validatedComments: CommentMatch[] = [];\n\n for (const comment of valid) {\n try {\n const validated = validateAndCorrectOffsets(content, comment.start, comment.end, comment.exact);\n validatedComments.push({\n ...comment,\n start: validated.start,\n end: validated.end,\n prefix: validated.prefix,\n suffix: validated.suffix\n });\n } catch (error) {\n console.warn(`[MotivationParsers] Skipping invalid comment \"${comment.exact}\":`, error);\n // Skip this comment - AI hallucinated text that doesn't exist\n }\n }\n\n return validatedComments;\n } catch (error) {\n console.error('[MotivationParsers] Failed to parse AI comment response:', error);\n return [];\n }\n }\n\n /**\n * Parse and validate AI response for highlight detection\n *\n * @param response - Raw AI response string (may include markdown code fences)\n * @param content - Original content to validate offsets against\n * @returns Array of validated highlight matches\n */\n static parseHighlights(response: string, content: string): HighlightMatch[] {\n try {\n // Clean up response - remove markdown code fences if present\n let cleaned = response.trim();\n if (cleaned.startsWith('```json') || cleaned.startsWith('```')) {\n cleaned = cleaned.slice(cleaned.indexOf('\\n') + 1);\n const endIndex = cleaned.lastIndexOf('```');\n if (endIndex !== -1) {\n cleaned = cleaned.slice(0, endIndex);\n }\n }\n\n const parsed = JSON.parse(cleaned);\n if (!Array.isArray(parsed)) {\n console.warn('[MotivationParsers] Highlight response was not an array');\n return [];\n }\n\n // Validate and filter results\n const highlights = parsed.filter((h: any) =>\n h && typeof h.exact === 'string' &&\n typeof h.start === 'number' &&\n typeof h.end === 'number'\n );\n\n // Validate and correct AI's offsets, then extract proper context\n // AI sometimes returns offsets that don't match the actual text position\n const validatedHighlights: HighlightMatch[] = [];\n\n for (const highlight of highlights) {\n try {\n const validated = validateAndCorrectOffsets(content, highlight.start, highlight.end, highlight.exact);\n validatedHighlights.push({\n ...highlight,\n start: validated.start,\n end: validated.end,\n prefix: validated.prefix,\n suffix: validated.suffix\n });\n } catch (error) {\n console.warn(`[MotivationParsers] Skipping invalid highlight \"${highlight.exact}\":`, error);\n // Skip this highlight - AI hallucinated text that doesn't exist\n }\n }\n\n return validatedHighlights;\n } catch (error) {\n console.error('[MotivationParsers] Failed to parse AI highlight response:', error);\n console.error('Raw response:', response);\n return [];\n }\n }\n\n /**\n * Parse and validate AI response for assessment detection\n *\n * @param response - Raw AI response string (may include markdown code fences)\n * @param content - Original content to validate offsets against\n * @returns Array of validated assessment matches\n */\n static parseAssessments(response: string, content: string): AssessmentMatch[] {\n try {\n // Clean up response - remove markdown code fences if present\n let cleaned = response.trim();\n if (cleaned.startsWith('```json') || cleaned.startsWith('```')) {\n cleaned = cleaned.slice(cleaned.indexOf('\\n') + 1);\n const endIndex = cleaned.lastIndexOf('```');\n if (endIndex !== -1) {\n cleaned = cleaned.slice(0, endIndex);\n }\n }\n\n const parsed = JSON.parse(cleaned);\n if (!Array.isArray(parsed)) {\n console.warn('[MotivationParsers] Assessment response was not an array');\n return [];\n }\n\n // Validate and filter results\n const assessments = parsed.filter((a: any) =>\n a && typeof a.exact === 'string' &&\n typeof a.start === 'number' &&\n typeof a.end === 'number' &&\n typeof a.assessment === 'string'\n );\n\n // Validate and correct AI's offsets, then extract proper context\n // AI sometimes returns offsets that don't match the actual text position\n const validatedAssessments: AssessmentMatch[] = [];\n\n for (const assessment of assessments) {\n try {\n const validated = validateAndCorrectOffsets(content, assessment.start, assessment.end, assessment.exact);\n validatedAssessments.push({\n ...assessment,\n start: validated.start,\n end: validated.end,\n prefix: validated.prefix,\n suffix: validated.suffix\n });\n } catch (error) {\n console.warn(`[MotivationParsers] Skipping invalid assessment \"${assessment.exact}\":`, error);\n // Skip this assessment - AI hallucinated text that doesn't exist\n }\n }\n\n return validatedAssessments;\n } catch (error) {\n console.error('[MotivationParsers] Failed to parse AI assessment response:', error);\n console.error('Raw response:', response);\n return [];\n }\n }\n\n /**\n * Parse and validate AI response for tag detection\n * Note: Does NOT validate offsets - caller must do that with content\n *\n * @param response - Raw AI response string (may include markdown code fences)\n * @returns Array of tag matches (offsets not yet validated)\n */\n static parseTags(response: string): Omit<TagMatch, 'category'>[] {\n try {\n // Clean up markdown code fences if present\n let cleaned = response.trim();\n if (cleaned.startsWith('```')) {\n cleaned = cleaned.replace(/^```(?:json)?\\n?/, '').replace(/\\n?```$/, '');\n }\n\n const parsed = JSON.parse(cleaned);\n\n if (!Array.isArray(parsed)) {\n console.warn('[MotivationParsers] Tag response is not an array');\n return [];\n }\n\n // Validate and filter\n const valid = parsed.filter((t: any) =>\n t &&\n typeof t.exact === 'string' &&\n typeof t.start === 'number' &&\n typeof t.end === 'number' &&\n t.exact.trim().length > 0\n );\n\n console.log(`[MotivationParsers] Parsed ${valid.length} valid tags from ${parsed.length} total`);\n\n return valid;\n } catch (error) {\n console.error('[MotivationParsers] Failed to parse AI tag response:', error);\n return [];\n }\n }\n\n /**\n * Validate tag offsets against content and add category\n * Helper for tag detection after initial parsing\n *\n * @param tags - Parsed tags without validated offsets\n * @param content - Original content to validate against\n * @param category - Category to assign to validated tags\n * @returns Array of validated tag matches\n */\n static validateTagOffsets(\n tags: Omit<TagMatch, 'category'>[],\n content: string,\n category: string\n ): TagMatch[] {\n const validatedTags: TagMatch[] = [];\n\n for (const tag of tags) {\n try {\n const validated = validateAndCorrectOffsets(content, tag.start, tag.end, tag.exact);\n validatedTags.push({\n ...tag,\n category,\n start: validated.start,\n end: validated.end,\n prefix: validated.prefix,\n suffix: validated.suffix\n });\n } catch (error) {\n console.warn(`[MotivationParsers] Skipping invalid tag for category \"${category}\":`, error);\n // Skip this tag - AI hallucinated text that doesn't exist\n }\n }\n\n return validatedTags;\n }\n}\n","// @semiont/make-meaning - Making meaning from resources\n// Transforms raw resources into meaningful, interconnected knowledge\n\n// Service (primary export)\nexport { startMakeMeaning } from './service';\nexport type { MakeMeaningService } from './service';\n\n// Graph Consumer\nexport { GraphDBConsumer } from './graph/consumer';\n\n// Context assembly exports\nexport { ResourceContext } from './resource-context';\nexport type { ListResourcesFilters } from './resource-context';\nexport { AnnotationContext } from './annotation-context';\nexport type { BuildContextOptions } from './annotation-context';\nexport { GraphContext } from './graph-context';\n\n// Detection exports\nexport { AnnotationDetection } from './annotation-detection';\nexport { MotivationPrompts } from './detection/motivation-prompts';\nexport { MotivationParsers } from './detection/motivation-parsers';\nexport type {\n CommentMatch,\n HighlightMatch,\n AssessmentMatch,\n TagMatch,\n} from './detection/motivation-parsers';\nexport { extractEntities } from './detection/entity-extractor';\nexport type { ExtractedEntity } from './detection/entity-extractor';\n\n// Generation exports\nexport {\n generateResourceFromTopic,\n generateResourceSummary,\n generateReferenceSuggestions,\n} from './generation/resource-generation';\n\n// Job workers (exported for direct instantiation if needed)\nexport { CommentDetectionWorker } from './jobs/comment-detection-worker';\nexport { HighlightDetectionWorker } from './jobs/highlight-detection-worker';\nexport { AssessmentDetectionWorker } from './jobs/assessment-detection-worker';\nexport { TagDetectionWorker } from './jobs/tag-detection-worker';\nexport { ReferenceDetectionWorker } from './jobs/reference-detection-worker';\nexport { GenerationWorker } from './jobs/generation-worker';\n\n// Reasoning exports (future)\n// export { ResourceReasoning } from './resource-reasoning';\n\n// Placeholder for initial build\nexport const PACKAGE_NAME = '@semiont/make-meaning';\nexport const VERSION = '0.1.0';\n"],"mappings":"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","names":["FilesystemRepresentationStore","makeResourceId","JobWorker","FilesystemRepresentationStore","response","JobWorker","FilesystemRepresentationStore","FilesystemViewStorage","JobWorker","generateAnnotationId","resourceIdToURI","JobWorker","resourceId","annotationId","resourceUri","JobWorker","generateAnnotationId","resourceIdToURI","userId","JobWorker","resourceId","annotationId","resourceUri","JobWorker","generateAnnotationId","resourceIdToURI","userId","JobWorker","resourceId","resourceUri","annotationId","JobWorker","generateAnnotationId","resourceIdToURI","userId","JobWorker","resourceId","resourceUri","annotationId","resourceUri","resourceId","annotationUri","FilesystemRepresentationStore","resourceId","makeResourceId","FilesystemRepresentationStore","getPrimaryRepresentation","decodeRepresentation","resourceId","getInferenceClient","getTargetSelector","getPrimaryRepresentation","decodeRepresentation","FilesystemRepresentationStore","FilesystemViewStorage","getEntityTypes","annotationUri","resourceId","FilesystemViewStorage","FilesystemRepresentationStore","targetResourceId","getPrimaryRepresentation","decodeRepresentation","getTargetSelector","getInferenceClient","getEntityTypes","annotationId","getGraphDatabase","resourceIdToURI","resourceId","resourceUri","FilesystemRepresentationStore","getPrimaryRepresentation","decodeRepresentation","validateAndCorrectOffsets","getTagSchema","resourceId","getPrimaryRepresentation","FilesystemRepresentationStore","decodeRepresentation"]}