@semiont/ontology 0.2.28-build.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,198 @@
1
+ # @semiont/ontology
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@semiont/ontology)](https://www.npmjs.com/package/@semiont/ontology)
4
+ [![Tests](https://github.com/The-AI-Alliance/semiont/actions/workflows/package-tests.yml/badge.svg)](https://github.com/The-AI-Alliance/semiont/actions/workflows/package-tests.yml?query=branch%3Amain+is%3Asuccess+job%3A%22Test+ontology%22)
5
+
6
+ Entity types, tag schemas, and tag extraction utilities for the Semiont annotation system.
7
+
8
+ ## Overview
9
+
10
+ This package consolidates ontology-related code that was previously scattered across the codebase:
11
+ - **Entity types**: Semantic categories for tagging resources and annotations (Person, Organization, Location, etc.)
12
+ - **Tag schemas**: Structural analysis frameworks (IRAC for legal, IMRAD for scientific, Toulmin for argumentation)
13
+ - **Tag extraction**: Utilities for extracting tag information from W3C annotations
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @semiont/ontology
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ### Entity Types
24
+
25
+ Default entity types used throughout the system:
26
+
27
+ ```typescript
28
+ import { DEFAULT_ENTITY_TYPES } from '@semiont/ontology';
29
+
30
+ console.log(DEFAULT_ENTITY_TYPES);
31
+ // ['Person', 'Organization', 'Location', 'Event', 'Concept',
32
+ // 'Product', 'Technology', 'Date', 'Author']
33
+ ```
34
+
35
+ ### Tag Schemas
36
+
37
+ Three built-in tag schemas for structural document analysis:
38
+
39
+ ```typescript
40
+ import {
41
+ TAG_SCHEMAS,
42
+ getTagSchema,
43
+ getAllTagSchemas,
44
+ getTagSchemasByDomain
45
+ } from '@semiont/ontology';
46
+
47
+ // Get a specific schema
48
+ const iracSchema = getTagSchema('legal-irac');
49
+ // Returns: { id: 'legal-irac', name: 'Legal Analysis (IRAC)',
50
+ // domain: 'legal', tags: [...] }
51
+
52
+ // Get all schemas
53
+ const allSchemas = getAllTagSchemas();
54
+ // Returns array of all 3 schemas
55
+
56
+ // Get schemas by domain
57
+ const legalSchemas = getTagSchemasByDomain('legal');
58
+ // Returns schemas where domain === 'legal'
59
+ ```
60
+
61
+ Available schemas (from [src/tag-schemas.ts](src/tag-schemas.ts)):
62
+ - `legal-irac`: Legal Analysis (IRAC) - Issue, Rule, Application, Conclusion
63
+ - `scientific-imrad`: Scientific Paper (IMRAD) - Introduction, Methods, Results, Discussion
64
+ - `argument-toulmin`: Argument Structure (Toulmin) - Claim, Evidence, Warrant, Counterargument, Rebuttal
65
+
66
+ ### Entity Extraction
67
+
68
+ Extract entity types from annotation bodies:
69
+
70
+ ```typescript
71
+ import { getEntityTypes } from '@semiont/ontology';
72
+ import type { components } from '@semiont/api-client';
73
+
74
+ type Annotation = components['schemas']['Annotation'];
75
+
76
+ const annotation: Annotation = {
77
+ motivation: 'linking',
78
+ body: [
79
+ { type: 'TextualBody', purpose: 'tagging', value: 'Person' },
80
+ { type: 'TextualBody', purpose: 'tagging', value: 'Organization' },
81
+ { type: 'SpecificResource', source: 'resource://abc123' }
82
+ ],
83
+ target: 'resource://xyz789'
84
+ };
85
+
86
+ const entityTypes = getEntityTypes(annotation);
87
+ // Returns: ['Person', 'Organization']
88
+ ```
89
+
90
+ From [src/entity-extraction.ts](src/entity-extraction.ts): Extracts values from `TextualBody` items where `purpose === 'tagging'`.
91
+
92
+ ### Tag Extraction
93
+
94
+ Extract tag categories and schema IDs from tag annotations:
95
+
96
+ ```typescript
97
+ import { getTagCategory, getTagSchemaId } from '@semiont/ontology';
98
+
99
+ const tagAnnotation = {
100
+ motivation: 'tagging',
101
+ body: [
102
+ { type: 'TextualBody', purpose: 'tagging', value: 'Issue' },
103
+ { type: 'TextualBody', purpose: 'classifying', value: 'legal-irac' }
104
+ ],
105
+ target: { source: 'resource://doc123', selector: { /* ... */ } }
106
+ };
107
+
108
+ const category = getTagCategory(tagAnnotation);
109
+ // Returns: 'Issue'
110
+
111
+ const schemaId = getTagSchemaId(tagAnnotation);
112
+ // Returns: 'legal-irac'
113
+ ```
114
+
115
+ From [src/tag-extraction.ts](src/tag-extraction.ts): Tag annotations use dual-body structure with `purpose: 'tagging'` for category and `purpose: 'classifying'` for schema ID.
116
+
117
+ ### Tag Schema Helpers
118
+
119
+ ```typescript
120
+ import { isValidCategory, getSchemaCategory } from '@semiont/ontology';
121
+
122
+ // Check if a category exists in a schema
123
+ const isValid = isValidCategory('legal-irac', 'Issue');
124
+ // Returns: true
125
+
126
+ const invalid = isValidCategory('legal-irac', 'Conclusion');
127
+ // Returns: true (all 4 IRAC categories are valid)
128
+
129
+ const notValid = isValidCategory('legal-irac', 'Introduction');
130
+ // Returns: false (Introduction is IMRAD, not IRAC)
131
+
132
+ // Get category details
133
+ const category = getSchemaCategory('legal-irac', 'Rule');
134
+ // Returns: {
135
+ // name: 'Rule',
136
+ // description: 'The relevant law, statute, or legal principle',
137
+ // examples: ['What law applies?', 'What is the legal standard?', ...]
138
+ // }
139
+ ```
140
+
141
+ ## Tag Collections
142
+
143
+ Type definitions for graph database tag collection operations:
144
+
145
+ ```typescript
146
+ import type { TagCollection, TagCollectionOperations } from '@semiont/ontology';
147
+
148
+ // TagCollection interface for stored collections
149
+ interface TagCollection {
150
+ id: string;
151
+ collectionType: 'entity-types';
152
+ tags: string[];
153
+ created: Date;
154
+ updatedAt: Date;
155
+ }
156
+
157
+ // TagCollectionOperations interface for graph database implementations
158
+ interface TagCollectionOperations {
159
+ getEntityTypes(): Promise<string[]>;
160
+ addEntityType(tag: string): Promise<void>;
161
+ addEntityTypes(tags: string[]): Promise<void>;
162
+ hasEntityTypesCollection(): Promise<boolean>;
163
+ initializeCollections(): Promise<void>;
164
+ }
165
+ ```
166
+
167
+ From [src/tag-collections.ts](src/tag-collections.ts): Interfaces for managing entity type collections in graph databases.
168
+
169
+ ## Dependencies
170
+
171
+ - `@semiont/api-client`: For W3C annotation type definitions
172
+
173
+ ## Package Structure
174
+
175
+ ```
176
+ packages/ontology/
177
+ ├── src/
178
+ │ ├── index.ts # Public API exports
179
+ │ ├── entity-types.ts # DEFAULT_ENTITY_TYPES
180
+ │ ├── tag-collections.ts # TagCollection interfaces
181
+ │ ├── tag-schemas.ts # TAG_SCHEMAS registry
182
+ │ ├── entity-extraction.ts # getEntityTypes utility
183
+ │ ├── tag-extraction.ts # getTagCategory, getTagSchemaId
184
+ │ └── bootstrap.ts # Re-export note (actual bootstrap in backend)
185
+ ├── package.json
186
+ ├── tsconfig.json
187
+ ├── tsup.config.ts
188
+ └── README.md
189
+ ```
190
+
191
+ ## Notes
192
+
193
+ - **Bootstrap service**: The entity types bootstrap logic remains in `apps/backend/src/bootstrap/entity-types-bootstrap.ts` to avoid circular dependency with `@semiont/core`.
194
+ - **Annotation type guards**: Type guards like `isHighlight()`, `isReference()`, etc. remain in `@semiont/api-client` as the OpenAPI spec is the source of truth for W3C motivations.
195
+
196
+ ## License
197
+
198
+ Apache-2.0
@@ -0,0 +1,132 @@
1
+ import { components } from '@semiont/api-client';
2
+
3
+ /**
4
+ * Default entity types for the Semiont system
5
+ *
6
+ * Entity types are used to tag resources and annotations with semantic categories.
7
+ * These types serve as initial seed data for the entity types collection.
8
+ */
9
+ declare const DEFAULT_ENTITY_TYPES: string[];
10
+
11
+ /**
12
+ * Tag Collections Management
13
+ *
14
+ * Stores entity types in the graph database as append-only collections.
15
+ * Provides interface for graph database implementations to manage entity type collections.
16
+ */
17
+ interface TagCollection {
18
+ id: string;
19
+ collectionType: 'entity-types';
20
+ tags: string[];
21
+ created: Date;
22
+ updatedAt: Date;
23
+ }
24
+ interface TagCollectionOperations {
25
+ /**
26
+ * Get or create collections with auto-seeding
27
+ */
28
+ getEntityTypes(): Promise<string[]>;
29
+ /**
30
+ * Append new tag (no duplicates)
31
+ */
32
+ addEntityType(tag: string): Promise<void>;
33
+ /**
34
+ * Bulk append tags
35
+ */
36
+ addEntityTypes(tags: string[]): Promise<void>;
37
+ /**
38
+ * Check if collections exist
39
+ */
40
+ hasEntityTypesCollection(): Promise<boolean>;
41
+ /**
42
+ * Initialize collections with seed data if they don't exist
43
+ */
44
+ initializeCollections(): Promise<void>;
45
+ }
46
+
47
+ /**
48
+ * Tag Schema Registry
49
+ *
50
+ * Defines structural analysis frameworks for automatic tagging detection.
51
+ * Each schema provides categories that passages can be classified into
52
+ * based on their structural role (not their semantic content).
53
+ *
54
+ * Examples: IRAC (legal), IMRAD (scientific), Toulmin (argumentation)
55
+ */
56
+ interface TagCategory {
57
+ name: string;
58
+ description: string;
59
+ examples: string[];
60
+ }
61
+ interface TagSchema {
62
+ id: string;
63
+ name: string;
64
+ description: string;
65
+ domain: 'legal' | 'scientific' | 'general';
66
+ tags: TagCategory[];
67
+ }
68
+ declare const TAG_SCHEMAS: Record<string, TagSchema>;
69
+ /**
70
+ * Get a tag schema by ID
71
+ */
72
+ declare function getTagSchema(schemaId: string): TagSchema | null;
73
+ /**
74
+ * Get all available tag schemas
75
+ */
76
+ declare function getAllTagSchemas(): TagSchema[];
77
+ /**
78
+ * Get tag schemas filtered by domain
79
+ */
80
+ declare function getTagSchemasByDomain(domain: 'legal' | 'scientific' | 'general'): TagSchema[];
81
+ /**
82
+ * Validate that a category name is valid for a schema
83
+ */
84
+ declare function isValidCategory(schemaId: string, categoryName: string): boolean;
85
+ /**
86
+ * Get a specific category from a schema
87
+ */
88
+ declare function getSchemaCategory(schemaId: string, categoryName: string): TagCategory | null;
89
+
90
+ /**
91
+ * Entity Type Extraction Utilities
92
+ *
93
+ * Extract entity types from annotation bodies.
94
+ * Entity types are stored as TextualBody with purpose: "tagging"
95
+ */
96
+
97
+ type Annotation$1 = components['schemas']['Annotation'];
98
+ /**
99
+ * Extract entity types from annotation bodies
100
+ * Entity types are stored as TextualBody with purpose: "tagging"
101
+ * Accepts any object with a body property matching Annotation['body']
102
+ */
103
+ declare function getEntityTypes(annotation: {
104
+ body: Annotation$1['body'];
105
+ }): string[];
106
+
107
+ /**
108
+ * Tag Schema Extraction Utilities
109
+ *
110
+ * Extract tag categories and schema IDs from tag annotations.
111
+ * Tags use dual-body structure:
112
+ * - First body has purpose: "tagging" with category value
113
+ * - Second body has purpose: "classifying" with schema ID
114
+ */
115
+
116
+ type Annotation = components['schemas']['Annotation'];
117
+ /**
118
+ * Extract tag category from a tag annotation's body
119
+ * Tags use dual-body structure: first body has purpose: "tagging" with category value
120
+ * @param annotation - The annotation to extract category from
121
+ * @returns The tag category (e.g., "Issue", "Rule"), or undefined if not a tag or no category found
122
+ */
123
+ declare function getTagCategory(annotation: Annotation): string | undefined;
124
+ /**
125
+ * Extract tag schema ID from a tag annotation's body
126
+ * Tags use dual-body structure: second body has purpose: "classifying" with schema ID
127
+ * @param annotation - The annotation to extract schema ID from
128
+ * @returns The schema ID (e.g., "legal-irac"), or undefined if not a tag or no schema found
129
+ */
130
+ declare function getTagSchemaId(annotation: Annotation): string | undefined;
131
+
132
+ export { DEFAULT_ENTITY_TYPES, TAG_SCHEMAS, type TagCategory, type TagCollection, type TagCollectionOperations, type TagSchema, getAllTagSchemas, getEntityTypes, getSchemaCategory, getTagCategory, getTagSchema, getTagSchemaId, getTagSchemasByDomain, isValidCategory };
package/dist/index.js ADDED
@@ -0,0 +1,231 @@
1
+ // src/entity-types.ts
2
+ var DEFAULT_ENTITY_TYPES = [
3
+ "Person",
4
+ "Organization",
5
+ "Location",
6
+ "Event",
7
+ "Concept",
8
+ "Product",
9
+ "Technology",
10
+ "Date",
11
+ "Author"
12
+ ];
13
+
14
+ // src/tag-schemas.ts
15
+ var TAG_SCHEMAS = {
16
+ "legal-irac": {
17
+ id: "legal-irac",
18
+ name: "Legal Analysis (IRAC)",
19
+ description: "Issue, Rule, Application, Conclusion framework for legal reasoning",
20
+ domain: "legal",
21
+ tags: [
22
+ {
23
+ name: "Issue",
24
+ description: "The legal question or problem to be resolved",
25
+ examples: [
26
+ "What is the central legal question?",
27
+ "What must the court decide?",
28
+ "What is the dispute about?"
29
+ ]
30
+ },
31
+ {
32
+ name: "Rule",
33
+ description: "The relevant law, statute, or legal principle",
34
+ examples: [
35
+ "What law applies?",
36
+ "What is the legal standard?",
37
+ "What statute governs this case?"
38
+ ]
39
+ },
40
+ {
41
+ name: "Application",
42
+ description: "How the rule applies to the specific facts",
43
+ examples: [
44
+ "How does the law apply to these facts?",
45
+ "Analysis of the case",
46
+ "How do the facts satisfy the legal standard?"
47
+ ]
48
+ },
49
+ {
50
+ name: "Conclusion",
51
+ description: "The resolution or outcome based on the analysis",
52
+ examples: [
53
+ "What is the court's decision?",
54
+ "What is the final judgment?",
55
+ "What is the holding?"
56
+ ]
57
+ }
58
+ ]
59
+ },
60
+ "scientific-imrad": {
61
+ id: "scientific-imrad",
62
+ name: "Scientific Paper (IMRAD)",
63
+ description: "Introduction, Methods, Results, Discussion structure for research papers",
64
+ domain: "scientific",
65
+ tags: [
66
+ {
67
+ name: "Introduction",
68
+ description: "Background, context, and research question",
69
+ examples: [
70
+ "What is the research question?",
71
+ "Why is this important?",
72
+ "What is the hypothesis?"
73
+ ]
74
+ },
75
+ {
76
+ name: "Methods",
77
+ description: "Experimental design and procedures",
78
+ examples: [
79
+ "How was the study conducted?",
80
+ "What methods were used?",
81
+ "What was the experimental design?"
82
+ ]
83
+ },
84
+ {
85
+ name: "Results",
86
+ description: "Findings and observations",
87
+ examples: [
88
+ "What did the study find?",
89
+ "What are the data?",
90
+ "What were the observations?"
91
+ ]
92
+ },
93
+ {
94
+ name: "Discussion",
95
+ description: "Interpretation and implications of results",
96
+ examples: [
97
+ "What do the results mean?",
98
+ "What are the implications?",
99
+ "How do these findings relate to prior work?"
100
+ ]
101
+ }
102
+ ]
103
+ },
104
+ "argument-toulmin": {
105
+ id: "argument-toulmin",
106
+ name: "Argument Structure (Toulmin)",
107
+ description: "Claim, Evidence, Warrant, Counterargument, Rebuttal framework for argumentation",
108
+ domain: "general",
109
+ tags: [
110
+ {
111
+ name: "Claim",
112
+ description: "The main assertion or thesis",
113
+ examples: [
114
+ "What is being argued?",
115
+ "What is the main point?",
116
+ "What position is being taken?"
117
+ ]
118
+ },
119
+ {
120
+ name: "Evidence",
121
+ description: "Data or facts supporting the claim",
122
+ examples: [
123
+ "What supports this claim?",
124
+ "What are the facts?",
125
+ "What data is provided?"
126
+ ]
127
+ },
128
+ {
129
+ name: "Warrant",
130
+ description: "Reasoning connecting evidence to claim",
131
+ examples: [
132
+ "Why does this evidence support the claim?",
133
+ "What is the logic?",
134
+ "How does this reasoning work?"
135
+ ]
136
+ },
137
+ {
138
+ name: "Counterargument",
139
+ description: "Opposing viewpoints or objections",
140
+ examples: [
141
+ "What are the objections?",
142
+ "What do critics say?",
143
+ "What are alternative views?"
144
+ ]
145
+ },
146
+ {
147
+ name: "Rebuttal",
148
+ description: "Response to counterarguments",
149
+ examples: [
150
+ "How is the objection addressed?",
151
+ "Why is the counterargument wrong?",
152
+ "How is the criticism answered?"
153
+ ]
154
+ }
155
+ ]
156
+ }
157
+ };
158
+ function getTagSchema(schemaId) {
159
+ return TAG_SCHEMAS[schemaId] || null;
160
+ }
161
+ function getAllTagSchemas() {
162
+ return Object.values(TAG_SCHEMAS);
163
+ }
164
+ function getTagSchemasByDomain(domain) {
165
+ return Object.values(TAG_SCHEMAS).filter((schema) => schema.domain === domain);
166
+ }
167
+ function isValidCategory(schemaId, categoryName) {
168
+ const schema = getTagSchema(schemaId);
169
+ if (!schema) return false;
170
+ return schema.tags.some((tag) => tag.name === categoryName);
171
+ }
172
+ function getSchemaCategory(schemaId, categoryName) {
173
+ const schema = getTagSchema(schemaId);
174
+ if (!schema) return null;
175
+ return schema.tags.find((tag) => tag.name === categoryName) || null;
176
+ }
177
+
178
+ // src/entity-extraction.ts
179
+ function getEntityTypes(annotation) {
180
+ if (Array.isArray(annotation.body)) {
181
+ const entityTags = [];
182
+ for (const item of annotation.body) {
183
+ if (typeof item === "object" && item !== null && "type" in item && "value" in item && "purpose" in item) {
184
+ const itemType = item.type;
185
+ const itemValue = item.value;
186
+ const itemPurpose = item.purpose;
187
+ if (itemType === "TextualBody" && itemPurpose === "tagging" && typeof itemValue === "string" && itemValue.length > 0) {
188
+ entityTags.push(itemValue);
189
+ }
190
+ }
191
+ }
192
+ return entityTags;
193
+ }
194
+ return [];
195
+ }
196
+
197
+ // src/tag-extraction.ts
198
+ function isTag(annotation) {
199
+ return annotation.motivation === "tagging";
200
+ }
201
+ function getTagCategory(annotation) {
202
+ if (!isTag(annotation)) return void 0;
203
+ const bodies = Array.isArray(annotation.body) ? annotation.body : [annotation.body];
204
+ const taggingBody = bodies.find((b) => b && "purpose" in b && b.purpose === "tagging");
205
+ if (taggingBody && "value" in taggingBody) {
206
+ return taggingBody.value;
207
+ }
208
+ return void 0;
209
+ }
210
+ function getTagSchemaId(annotation) {
211
+ if (!isTag(annotation)) return void 0;
212
+ const bodies = Array.isArray(annotation.body) ? annotation.body : [annotation.body];
213
+ const classifyingBody = bodies.find((b) => b && "purpose" in b && b.purpose === "classifying");
214
+ if (classifyingBody && "value" in classifyingBody) {
215
+ return classifyingBody.value;
216
+ }
217
+ return void 0;
218
+ }
219
+ export {
220
+ DEFAULT_ENTITY_TYPES,
221
+ TAG_SCHEMAS,
222
+ getAllTagSchemas,
223
+ getEntityTypes,
224
+ getSchemaCategory,
225
+ getTagCategory,
226
+ getTagSchema,
227
+ getTagSchemaId,
228
+ getTagSchemasByDomain,
229
+ isValidCategory
230
+ };
231
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/entity-types.ts","../src/tag-schemas.ts","../src/entity-extraction.ts","../src/tag-extraction.ts"],"sourcesContent":["/**\n * Default entity types for the Semiont system\n *\n * Entity types are used to tag resources and annotations with semantic categories.\n * These types serve as initial seed data for the entity types collection.\n */\nexport const DEFAULT_ENTITY_TYPES = [\n 'Person',\n 'Organization',\n 'Location',\n 'Event',\n 'Concept',\n 'Product',\n 'Technology',\n 'Date',\n 'Author'\n];\n","/**\n * Tag Schema Registry\n *\n * Defines structural analysis frameworks for automatic tagging detection.\n * Each schema provides categories that passages can be classified into\n * based on their structural role (not their semantic content).\n *\n * Examples: IRAC (legal), IMRAD (scientific), Toulmin (argumentation)\n */\n\nexport interface TagCategory {\n name: string;\n description: string;\n examples: string[];\n}\n\nexport interface TagSchema {\n id: string;\n name: string;\n description: string;\n domain: 'legal' | 'scientific' | 'general';\n tags: TagCategory[];\n}\n\nexport const TAG_SCHEMAS: Record<string, TagSchema> = {\n 'legal-irac': {\n id: 'legal-irac',\n name: 'Legal Analysis (IRAC)',\n description: 'Issue, Rule, Application, Conclusion framework for legal reasoning',\n domain: 'legal',\n tags: [\n {\n name: 'Issue',\n description: 'The legal question or problem to be resolved',\n examples: [\n 'What is the central legal question?',\n 'What must the court decide?',\n 'What is the dispute about?'\n ]\n },\n {\n name: 'Rule',\n description: 'The relevant law, statute, or legal principle',\n examples: [\n 'What law applies?',\n 'What is the legal standard?',\n 'What statute governs this case?'\n ]\n },\n {\n name: 'Application',\n description: 'How the rule applies to the specific facts',\n examples: [\n 'How does the law apply to these facts?',\n 'Analysis of the case',\n 'How do the facts satisfy the legal standard?'\n ]\n },\n {\n name: 'Conclusion',\n description: 'The resolution or outcome based on the analysis',\n examples: [\n 'What is the court\\'s decision?',\n 'What is the final judgment?',\n 'What is the holding?'\n ]\n }\n ]\n },\n\n 'scientific-imrad': {\n id: 'scientific-imrad',\n name: 'Scientific Paper (IMRAD)',\n description: 'Introduction, Methods, Results, Discussion structure for research papers',\n domain: 'scientific',\n tags: [\n {\n name: 'Introduction',\n description: 'Background, context, and research question',\n examples: [\n 'What is the research question?',\n 'Why is this important?',\n 'What is the hypothesis?'\n ]\n },\n {\n name: 'Methods',\n description: 'Experimental design and procedures',\n examples: [\n 'How was the study conducted?',\n 'What methods were used?',\n 'What was the experimental design?'\n ]\n },\n {\n name: 'Results',\n description: 'Findings and observations',\n examples: [\n 'What did the study find?',\n 'What are the data?',\n 'What were the observations?'\n ]\n },\n {\n name: 'Discussion',\n description: 'Interpretation and implications of results',\n examples: [\n 'What do the results mean?',\n 'What are the implications?',\n 'How do these findings relate to prior work?'\n ]\n }\n ]\n },\n\n 'argument-toulmin': {\n id: 'argument-toulmin',\n name: 'Argument Structure (Toulmin)',\n description: 'Claim, Evidence, Warrant, Counterargument, Rebuttal framework for argumentation',\n domain: 'general',\n tags: [\n {\n name: 'Claim',\n description: 'The main assertion or thesis',\n examples: [\n 'What is being argued?',\n 'What is the main point?',\n 'What position is being taken?'\n ]\n },\n {\n name: 'Evidence',\n description: 'Data or facts supporting the claim',\n examples: [\n 'What supports this claim?',\n 'What are the facts?',\n 'What data is provided?'\n ]\n },\n {\n name: 'Warrant',\n description: 'Reasoning connecting evidence to claim',\n examples: [\n 'Why does this evidence support the claim?',\n 'What is the logic?',\n 'How does this reasoning work?'\n ]\n },\n {\n name: 'Counterargument',\n description: 'Opposing viewpoints or objections',\n examples: [\n 'What are the objections?',\n 'What do critics say?',\n 'What are alternative views?'\n ]\n },\n {\n name: 'Rebuttal',\n description: 'Response to counterarguments',\n examples: [\n 'How is the objection addressed?',\n 'Why is the counterargument wrong?',\n 'How is the criticism answered?'\n ]\n }\n ]\n }\n};\n\n/**\n * Get a tag schema by ID\n */\nexport function getTagSchema(schemaId: string): TagSchema | null {\n return TAG_SCHEMAS[schemaId] || null;\n}\n\n/**\n * Get all available tag schemas\n */\nexport function getAllTagSchemas(): TagSchema[] {\n return Object.values(TAG_SCHEMAS);\n}\n\n/**\n * Get tag schemas filtered by domain\n */\nexport function getTagSchemasByDomain(domain: 'legal' | 'scientific' | 'general'): TagSchema[] {\n return Object.values(TAG_SCHEMAS).filter(schema => schema.domain === domain);\n}\n\n/**\n * Validate that a category name is valid for a schema\n */\nexport function isValidCategory(schemaId: string, categoryName: string): boolean {\n const schema = getTagSchema(schemaId);\n if (!schema) return false;\n return schema.tags.some(tag => tag.name === categoryName);\n}\n\n/**\n * Get a specific category from a schema\n */\nexport function getSchemaCategory(schemaId: string, categoryName: string): TagCategory | null {\n const schema = getTagSchema(schemaId);\n if (!schema) return null;\n return schema.tags.find(tag => tag.name === categoryName) || null;\n}\n","/**\n * Entity Type Extraction Utilities\n *\n * Extract entity types from annotation bodies.\n * Entity types are stored as TextualBody with purpose: \"tagging\"\n */\n\nimport type { components } from '@semiont/api-client';\n\ntype Annotation = components['schemas']['Annotation'];\n\n/**\n * Extract entity types from annotation bodies\n * Entity types are stored as TextualBody with purpose: \"tagging\"\n * Accepts any object with a body property matching Annotation['body']\n */\nexport function getEntityTypes(annotation: { body: Annotation['body'] }): string[] {\n // Extract from TextualBody bodies with purpose: \"tagging\"\n if (Array.isArray(annotation.body)) {\n const entityTags: string[] = [];\n\n for (const item of annotation.body) {\n // Runtime check for TextualBody with tagging purpose\n // TypeScript incorrectly narrows the union type here, so we use runtime checks only\n if (\n typeof item === 'object' &&\n item !== null &&\n 'type' in item &&\n 'value' in item &&\n 'purpose' in item\n ) {\n // Access properties as unknown first to avoid TypeScript narrowing issues\n const itemType = (item as { type: unknown }).type;\n const itemValue = (item as { value: unknown }).value;\n const itemPurpose = (item as { purpose: unknown }).purpose;\n\n if (itemType === 'TextualBody' && itemPurpose === 'tagging' && typeof itemValue === 'string' && itemValue.length > 0) {\n entityTags.push(itemValue);\n }\n }\n }\n\n return entityTags;\n }\n\n return [];\n}\n","/**\n * Tag Schema Extraction Utilities\n *\n * Extract tag categories and schema IDs from tag annotations.\n * Tags use dual-body structure:\n * - First body has purpose: \"tagging\" with category value\n * - Second body has purpose: \"classifying\" with schema ID\n */\n\nimport type { components } from '@semiont/api-client';\n\ntype Annotation = components['schemas']['Annotation'];\n\n/**\n * Type guard to check if an annotation is a tag\n */\nfunction isTag(annotation: Annotation): boolean {\n return annotation.motivation === 'tagging';\n}\n\n/**\n * Extract tag category from a tag annotation's body\n * Tags use dual-body structure: first body has purpose: \"tagging\" with category value\n * @param annotation - The annotation to extract category from\n * @returns The tag category (e.g., \"Issue\", \"Rule\"), or undefined if not a tag or no category found\n */\nexport function getTagCategory(annotation: Annotation): string | undefined {\n if (!isTag(annotation)) return undefined;\n const bodies = Array.isArray(annotation.body) ? annotation.body : [annotation.body];\n const taggingBody = bodies.find(b => b && 'purpose' in b && b.purpose === 'tagging');\n if (taggingBody && 'value' in taggingBody) {\n return taggingBody.value;\n }\n return undefined;\n}\n\n/**\n * Extract tag schema ID from a tag annotation's body\n * Tags use dual-body structure: second body has purpose: \"classifying\" with schema ID\n * @param annotation - The annotation to extract schema ID from\n * @returns The schema ID (e.g., \"legal-irac\"), or undefined if not a tag or no schema found\n */\nexport function getTagSchemaId(annotation: Annotation): string | undefined {\n if (!isTag(annotation)) return undefined;\n const bodies = Array.isArray(annotation.body) ? annotation.body : [annotation.body];\n const classifyingBody = bodies.find(b => b && 'purpose' in b && b.purpose === 'classifying');\n if (classifyingBody && 'value' in classifyingBody) {\n return classifyingBody.value;\n }\n return undefined;\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@semiont/ontology",
3
+ "version": "0.2.28-build.40",
4
+ "type": "module",
5
+ "description": "Entity types, tag schemas, and W3C annotation vocabularies",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "build": "npm run typecheck && tsup",
20
+ "typecheck": "tsc --noEmit",
21
+ "clean": "rm -rf dist",
22
+ "test": "vitest run",
23
+ "test:watch": "vitest"
24
+ },
25
+ "dependencies": {
26
+ "@semiont/api-client": "*"
27
+ },
28
+ "devDependencies": {
29
+ "tsup": "^8.0.1",
30
+ "typescript": "^5.6.3",
31
+ "vitest": "^3.2.4"
32
+ },
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "keywords": [
37
+ "ontology",
38
+ "entity-types",
39
+ "tag-schemas",
40
+ "w3c",
41
+ "annotations",
42
+ "vocabularies"
43
+ ],
44
+ "author": "The AI Alliance",
45
+ "license": "Apache-2.0",
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "https://github.com/The-AI-Alliance/semiont.git",
49
+ "directory": "packages/ontology"
50
+ }
51
+ }