objectivist-ner 0.0.1 → 0.0.2

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.
Files changed (3) hide show
  1. package/README.md +34 -0
  2. package/index.ts +38 -10
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -148,6 +148,39 @@ ner --relations "Dr. Chen works at MIT and collaborates with Prof. Wright"
148
148
 
149
149
  Relations show how entities connect — extracting the "connective tissue" between concepts.
150
150
 
151
+ You can also categorize relations by class:
152
+
153
+ ```bash
154
+ ner --relations --relation-classes "employment,location,causal,professional" \
155
+ "Dr. Chen works at MIT and collaborates with Prof. Wright"
156
+ ```
157
+
158
+ ```json
159
+ {
160
+ "entities": [
161
+ { "class": "person", "text": "Dr. Chen" },
162
+ { "class": "organization", "text": "MIT" },
163
+ { "class": "person", "text": "Prof. Wright" }
164
+ ],
165
+ "relations": [
166
+ {
167
+ "source": "Dr. Chen",
168
+ "target": "MIT",
169
+ "relation": "works at",
170
+ "class": "employment"
171
+ },
172
+ {
173
+ "source": "Dr. Chen",
174
+ "target": "Prof. Wright",
175
+ "relation": "collaborates with",
176
+ "class": "professional"
177
+ }
178
+ ]
179
+ }
180
+ ```
181
+
182
+ The `class` field categorizes the relation type (e.g., employment, causal, spatial), allowing you to group and analyze connections by category.
183
+
151
184
  ## Installation
152
185
 
153
186
  ```bash
@@ -274,6 +307,7 @@ cat article.txt | ner --detect-negation
274
307
  | `--attr-values <json>` | Enum map for attribute values |
275
308
  | `--taxonomy <json>` | Class hierarchy (parent → children) |
276
309
  | `--relations` | Extract relations between entities |
310
+ | `--relation-classes <list>` | Allowed relation classes (e.g. employment,causal) |
277
311
  | `--resolve` | Resolve coreferences (adds entity_id) |
278
312
  | `--detect-negation` | Add assertion field (present/negated/hypothetical) |
279
313
  | `--include-confidence` | Add confidence field (low/medium/high) |
package/index.ts CHANGED
@@ -44,6 +44,7 @@ interface SchemaFile {
44
44
  attributes?: string[];
45
45
  attrValues?: Record<string, string[]>;
46
46
  relations?: string[];
47
+ relationClasses?: string[];
47
48
  }
48
49
 
49
50
  // === TAXONOMY HELPERS ===
@@ -178,6 +179,10 @@ program
178
179
  'Class hierarchy JSON e.g. {"organism":["animal","plant"]}',
179
180
  )
180
181
  .option("--relations", "Extract relations between entities")
182
+ .option(
183
+ "--relation-classes <list>",
184
+ "Comma-separated allowed relation classes (e.g. employment,location,causal)",
185
+ )
181
186
  .option("--resolve", "Resolve coreferences (group mentions of same entity)")
182
187
  .option("--include-confidence", "Include confidence scores per entity")
183
188
  .option("--detect-negation", "Detect negated/hypothetical entities")
@@ -293,6 +298,9 @@ if (opts.taxonomy) {
293
298
 
294
299
  const enableRelations = opts.relations || !!schemaFile?.relations;
295
300
  const relationTypes: string[] | undefined = schemaFile?.relations || undefined;
301
+ const relationClasses: string[] | undefined = opts.relationClasses
302
+ ? opts.relationClasses.split(",").map((s: string) => s.trim())
303
+ : schemaFile?.relationClasses;
296
304
  const enableResolve = !!opts.resolve;
297
305
  const enableConfidence = !!opts.includeConfidence;
298
306
  const enableNegation = !!opts.detectNegation;
@@ -444,6 +452,23 @@ function buildGrammarSchema() {
444
452
 
445
453
  // === BUILD RELATIONS SCHEMA ===
446
454
  function buildRelationsSchema() {
455
+ const relationProperties: any = {
456
+ source: { type: "string" },
457
+ target: { type: "string" },
458
+ relation: {
459
+ type: "string",
460
+ ...(relationTypes && { enum: relationTypes }),
461
+ },
462
+ };
463
+
464
+ // Add class field if relationClasses is specified
465
+ if (relationClasses) {
466
+ relationProperties.class = {
467
+ type: "string",
468
+ enum: relationClasses,
469
+ };
470
+ }
471
+
447
472
  const relSchema: any = {
448
473
  type: "object",
449
474
  properties: {
@@ -452,15 +477,10 @@ function buildRelationsSchema() {
452
477
  type: "array",
453
478
  items: {
454
479
  type: "object",
455
- properties: {
456
- source: { type: "string" },
457
- target: { type: "string" },
458
- relation: {
459
- type: "string",
460
- ...(relationTypes && { enum: relationTypes }),
461
- },
462
- },
463
- required: ["source", "target", "relation"],
480
+ properties: relationProperties,
481
+ required: relationClasses
482
+ ? ["source", "target", "relation", "class"]
483
+ : ["source", "target", "relation"],
464
484
  additionalProperties: false,
465
485
  },
466
486
  },
@@ -500,10 +520,18 @@ function buildConstraints(): string {
500
520
  constraints += `\nEvery entity has "entity_id" and "is_canonical" fields. Coreferent mentions share entity_id; exactly one per group has is_canonical:true (the most specific reference). Example: [{"class":"person","text":"Dr. Chen","entity_id":"e1","is_canonical":true,"attributes":{}},{"class":"person","text":"She","entity_id":"e1","is_canonical":false,"attributes":{}}]`;
501
521
  }
502
522
  if (enableRelations) {
503
- constraints += `\nAlso extract relations between entities. Return {"entities": [...], "relations": [{"source": "entity text", "target": "entity text", "relation": "relation type"}]}.`;
523
+ let relDesc = `\nAlso extract relations between entities.`;
524
+ if (relationClasses) {
525
+ relDesc += ` Each relation must have a "class" field categorizing the relation type.`;
526
+ }
527
+ relDesc += ` Return {"entities": [...], "relations": [{"source": "entity text", "target": "entity text", "relation": "relation type"${relationClasses ? ', "class": "relation class"' : ""}}]}.`;
528
+ constraints += relDesc;
504
529
  if (relationTypes) {
505
530
  constraints += ` Allowed relation types: ${relationTypes.join(", ")}.`;
506
531
  }
532
+ if (relationClasses) {
533
+ constraints += ` Allowed relation classes: ${relationClasses.join(", ")}.`;
534
+ }
507
535
  }
508
536
 
509
537
  return constraints;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "objectivist-ner",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Objectivist-inspired Named Entity Recognition with grammar-constrained LLM output",
5
5
  "bin": {
6
6
  "ner": "index.ts"