@yottagraph-app/aether-instructions 1.1.18 → 1.1.20
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/commands/build_my_app.md +4 -1
- package/package.json +1 -1
- package/rules/aether.mdc +1 -1
- package/rules/agents.mdc +151 -2
- package/rules/api.mdc +108 -85
- package/rules/architecture.mdc +13 -8
- package/rules/cookbook.mdc +56 -18
- package/rules/design.mdc +3 -1
- package/rules/mcp-servers.mdc +1 -1
- package/rules/pref.mdc +16 -20
- package/rules/server.mdc +104 -0
- package/skills/data-model/newsdata/schema.yaml +10 -0
- package/skills/elemental-api/SKILL.md +4 -10
- package/skills/elemental-api/entities.md +37 -112
- package/skills/elemental-api/find.md +19 -4
- package/skills/elemental-api/graph.md +3 -3
- package/skills/elemental-api/overview.md +46 -22
- package/skills/elemental-api/schema.md +10 -30
- package/skills/elemental-api/articles.md +0 -386
- package/skills/elemental-api/events.md +0 -145
- package/skills/elemental-api/llm.md +0 -18
- package/skills/elemental-api/relationships.md +0 -310
- package/skills/elemental-api/sentiment.md +0 -93
package/rules/mcp-servers.mdc
CHANGED
|
@@ -102,7 +102,7 @@ Once deployed, agents can connect to your MCP server. Add the Cloud Run URL to y
|
|
|
102
102
|
|
|
103
103
|
- One server per data domain or external service
|
|
104
104
|
- Keep tools focused and well-documented
|
|
105
|
-
- Return structured data (dicts/lists), not raw strings
|
|
105
|
+
- Return structured data (dicts/lists), not raw strings — MCP handles serialization via the protocol. (This differs from ADK agent tools, which should return formatted strings because the LLM reads tool output directly — see the `agents` rule.)
|
|
106
106
|
- Handle errors by returning descriptive error messages in the response
|
|
107
107
|
- Use environment variables for API keys and configuration (never hardcode secrets)
|
|
108
108
|
- For secrets, use GCP Secret Manager and access at runtime
|
package/rules/pref.mdc
CHANGED
|
@@ -46,13 +46,25 @@ The backing store auto-initializes on first use — no need to call
|
|
|
46
46
|
|
|
47
47
|
## Local Development
|
|
48
48
|
|
|
49
|
-
KV credentials are only available
|
|
50
|
-
them at runtime). In local dev,
|
|
51
|
-
|
|
52
|
-
works with its default value but
|
|
49
|
+
KV credentials (`KV_REST_API_URL`, `KV_REST_API_TOKEN`) are only available
|
|
50
|
+
in deployed builds (Vercel auto-injects them at runtime). In local dev,
|
|
51
|
+
`getRedis()` returns `null` and KV routes return `undefined` for reads and
|
|
52
|
+
silently skip writes. `Pref<T>` still works with its default value but
|
|
53
|
+
won't persist across page refreshes.
|
|
53
54
|
|
|
54
55
|
This is expected — push to `main` and test persistence on the deployed build.
|
|
55
56
|
|
|
57
|
+
For local-only persistence, use `localStorage` as a lightweight alternative:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
const saved = localStorage.getItem('watchlist');
|
|
61
|
+
const watchlist = ref<string[]>(saved ? JSON.parse(saved) : []);
|
|
62
|
+
watch(watchlist, (val) => localStorage.setItem('watchlist', JSON.stringify(val)), { deep: true });
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Use `Pref<T>` for production persistence and `localStorage` for local-only
|
|
66
|
+
development when KV isn't available.
|
|
67
|
+
|
|
56
68
|
**Auth dependency:** All `/api/kv/*` routes call `unsealCookie(event)` to
|
|
57
69
|
identify the user. In dev mode (no `NUXT_PUBLIC_AUTH0_CLIENT_SECRET` set),
|
|
58
70
|
this is bypassed automatically using `NUXT_PUBLIC_USER_NAME`. If you set an
|
|
@@ -107,22 +119,6 @@ function useMyFeaturePrefs() {
|
|
|
107
119
|
- **Key format**: `prefs:users:{userId}:apps:{appId}:settings:general`
|
|
108
120
|
(doc-style paths converted to colon-separated Redis keys)
|
|
109
121
|
|
|
110
|
-
## Local Development Without KV
|
|
111
|
-
|
|
112
|
-
When KV credentials (`KV_REST_API_URL`, `KV_REST_API_TOKEN`) aren't configured,
|
|
113
|
-
`Pref<T>` still works with its default value but won't persist across page
|
|
114
|
-
refreshes. For local dev, use `localStorage` directly as a lightweight
|
|
115
|
-
alternative:
|
|
116
|
-
|
|
117
|
-
```typescript
|
|
118
|
-
const saved = localStorage.getItem('watchlist');
|
|
119
|
-
const watchlist = ref<string[]>(saved ? JSON.parse(saved) : []);
|
|
120
|
-
watch(watchlist, (val) => localStorage.setItem('watchlist', JSON.stringify(val)), { deep: true });
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
Use `Pref<T>` for production persistence and `localStorage` for local-only
|
|
124
|
-
development when KV isn't available.
|
|
125
|
-
|
|
126
122
|
## Scope Guidance
|
|
127
123
|
|
|
128
124
|
| App-specific | Global |
|
package/rules/server.mdc
CHANGED
|
@@ -158,6 +158,110 @@ export function getDb(): NeonQueryFunction | null {
|
|
|
158
158
|
}
|
|
159
159
|
```
|
|
160
160
|
|
|
161
|
+
## Calling the Elemental API from Server Routes
|
|
162
|
+
|
|
163
|
+
Server routes can call the Elemental API through the Portal Gateway proxy,
|
|
164
|
+
just like client-side code does. The gateway URL, tenant org ID, and API key
|
|
165
|
+
are available via `useRuntimeConfig()`.
|
|
166
|
+
|
|
167
|
+
**NEVER use `readFileSync('broadchurch.yaml')` in server routes.** The YAML
|
|
168
|
+
file is read at build time by `nuxt.config.ts` and its values flow into
|
|
169
|
+
`runtimeConfig`. Nitro serverless functions (Vercel) don't bundle arbitrary
|
|
170
|
+
project files — `readFileSync` will crash with ENOENT in production even
|
|
171
|
+
though it works locally.
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
export default defineEventHandler(async (event) => {
|
|
175
|
+
const { public: config } = useRuntimeConfig();
|
|
176
|
+
|
|
177
|
+
const gatewayUrl = config.gatewayUrl; // Portal Gateway base URL
|
|
178
|
+
const orgId = config.tenantOrgId; // Tenant org ID (path segment)
|
|
179
|
+
const apiKey = config.qsApiKey; // API key for X-Api-Key header
|
|
180
|
+
|
|
181
|
+
if (!gatewayUrl || !orgId) {
|
|
182
|
+
throw createError({ statusCode: 503, statusMessage: 'Gateway not configured' });
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const res = await $fetch(`${gatewayUrl}/api/qs/${orgId}/entities/search`, {
|
|
186
|
+
method: 'POST',
|
|
187
|
+
headers: {
|
|
188
|
+
'Content-Type': 'application/json',
|
|
189
|
+
...(apiKey && { 'X-Api-Key': apiKey }),
|
|
190
|
+
},
|
|
191
|
+
body: { queries: [{ queryId: 1, query: 'Microsoft' }], maxResults: 5 },
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
return res;
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Available runtime config keys (all under `runtimeConfig.public`):
|
|
199
|
+
|
|
200
|
+
| Key | Source | Purpose |
|
|
201
|
+
|---|---|---|
|
|
202
|
+
| `gatewayUrl` | `broadchurch.yaml` → `gateway.url` | Portal Gateway base URL |
|
|
203
|
+
| `tenantOrgId` | `broadchurch.yaml` → `tenant.org_id` | Tenant ID for API path |
|
|
204
|
+
| `qsApiKey` | `broadchurch.yaml` → `gateway.qs_api_key` | API key sent as `X-Api-Key` |
|
|
205
|
+
| `queryServerAddress` | `broadchurch.yaml` → `query_server.url` | Direct QS URL (prefer gateway) |
|
|
206
|
+
|
|
207
|
+
Build the request URL as `{gatewayUrl}/api/qs/{tenantOrgId}/{endpoint}`.
|
|
208
|
+
See the `api` rule for endpoint reference and response shapes.
|
|
209
|
+
|
|
210
|
+
## Neon Postgres: Handle Missing Tables in GET Routes
|
|
211
|
+
|
|
212
|
+
Tables created by POST/setup routes won't exist on a fresh deployment.
|
|
213
|
+
**Every GET route that queries a table must handle the case where the table
|
|
214
|
+
doesn't exist yet.** Without this, fresh deploys will 500 on every page load
|
|
215
|
+
until the setup route runs.
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
export default defineEventHandler(async () => {
|
|
219
|
+
const sql = getDb();
|
|
220
|
+
if (!sql) throw createError({ statusCode: 503, statusMessage: 'Database not configured' });
|
|
221
|
+
|
|
222
|
+
try {
|
|
223
|
+
const rows = await sql`SELECT * FROM companies ORDER BY updated_at DESC`;
|
|
224
|
+
return rows;
|
|
225
|
+
} catch (err: any) {
|
|
226
|
+
if (err.message?.includes('does not exist')) {
|
|
227
|
+
return [];
|
|
228
|
+
}
|
|
229
|
+
throw err;
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Alternatively, ensure tables exist before querying by calling
|
|
235
|
+
`CREATE TABLE IF NOT EXISTS` at the top of each GET route, or by calling a
|
|
236
|
+
shared setup function:
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
// server/utils/ensure-tables.ts
|
|
240
|
+
import { getDb } from '~/server/utils/neon';
|
|
241
|
+
|
|
242
|
+
let _initialized = false;
|
|
243
|
+
|
|
244
|
+
export async function ensureTables() {
|
|
245
|
+
if (_initialized) return;
|
|
246
|
+
const sql = getDb();
|
|
247
|
+
if (!sql) return;
|
|
248
|
+
|
|
249
|
+
await sql`CREATE TABLE IF NOT EXISTS companies (
|
|
250
|
+
id SERIAL PRIMARY KEY,
|
|
251
|
+
neid TEXT UNIQUE NOT NULL,
|
|
252
|
+
name TEXT NOT NULL,
|
|
253
|
+
data JSONB DEFAULT '{}',
|
|
254
|
+
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
255
|
+
)`;
|
|
256
|
+
|
|
257
|
+
_initialized = true;
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Then call `await ensureTables()` at the start of any route that reads the
|
|
262
|
+
table. The `_initialized` flag makes it a no-op after the first call within
|
|
263
|
+
the same serverless invocation.
|
|
264
|
+
|
|
161
265
|
## Key Differences from Client-Side Code
|
|
162
266
|
|
|
163
267
|
- Server routes run on the server (Node.js), not in the browser
|
|
@@ -62,12 +62,14 @@ flavors:
|
|
|
62
62
|
description: "A news article or press release being processed"
|
|
63
63
|
display_name: "Article"
|
|
64
64
|
mergeability: not_mergeable
|
|
65
|
+
strong_id_properties: ["newsdata_id"]
|
|
65
66
|
passive: true
|
|
66
67
|
|
|
67
68
|
- name: "publication"
|
|
68
69
|
description: "A news publication or media outlet identified by its home URL"
|
|
69
70
|
display_name: "Publication"
|
|
70
71
|
mergeability: not_mergeable
|
|
72
|
+
strong_id_properties: ["homeUrl"]
|
|
71
73
|
passive: true
|
|
72
74
|
|
|
73
75
|
# =============================================================================
|
|
@@ -389,6 +391,14 @@ properties:
|
|
|
389
391
|
domain_flavors: ["article"]
|
|
390
392
|
passive: true
|
|
391
393
|
|
|
394
|
+
- name: "newsdata_id"
|
|
395
|
+
type: string
|
|
396
|
+
description: "Unique article identifier from the NewsData API"
|
|
397
|
+
display_name: "NewsData ID"
|
|
398
|
+
mergeability: not_mergeable
|
|
399
|
+
domain_flavors: ["article"]
|
|
400
|
+
passive: true
|
|
401
|
+
|
|
392
402
|
- name: "title"
|
|
393
403
|
type: string
|
|
394
404
|
description: "Title of the entity"
|
|
@@ -11,17 +11,15 @@ This skill provides documentation for the Lovelace Elemental API, the primary in
|
|
|
11
11
|
|
|
12
12
|
Use this skill when you need to:
|
|
13
13
|
- Look up entities (companies, people, organizations) by name or ID
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
- Explore relationships and connections between entities
|
|
17
|
-
- Retrieve events involving specific entities
|
|
14
|
+
- Search for entities by type, property values, or relationships using the expression language
|
|
15
|
+
- Get entity metadata (types/flavors, properties)
|
|
18
16
|
- Build knowledge graphs of entity networks
|
|
19
17
|
|
|
20
18
|
## Quick Start
|
|
21
19
|
|
|
22
20
|
1. **Find an entity**: Use `entities.md` to look up a company or person by name and get their NEID (Named Entity ID)
|
|
23
|
-
2. **Get information**: Use the NEID to query
|
|
24
|
-
3. **
|
|
21
|
+
2. **Get information**: Use the NEID to query entity properties or explore the graph
|
|
22
|
+
3. **Search**: Use `find.md` for expression-based entity searches
|
|
25
23
|
|
|
26
24
|
## Files in This Skill
|
|
27
25
|
|
|
@@ -29,9 +27,5 @@ See [overview.md](overview.md) for descriptions of each endpoint category:
|
|
|
29
27
|
- `entities.md` - Entity search, details, and properties
|
|
30
28
|
- `find.md` - Expression language for searching entities by type, property values, and relationships
|
|
31
29
|
- `schema.md` - Data model: entity types (flavors), properties, and schema endpoints
|
|
32
|
-
- `sentiment.md` - Sentiment analysis
|
|
33
|
-
- `articles.md` - Articles mentioning entities and full article content
|
|
34
|
-
- `events.md` - Events involving entities
|
|
35
|
-
- `relationships.md` - Entity connections
|
|
36
30
|
- `graph.md` - Visual graph generation
|
|
37
31
|
- `server.md` - Server status and health
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Entities are the core objects in the Knowledge Graph: companies, people, organizations, products, and other named things that appear in the news. Each entity has a unique **Named Entity ID (NEID)**.
|
|
4
4
|
|
|
5
|
+
NEIDs are stable and can be persisted long-term, but may occasionally change if the database is rebuilt or the application switches databases. When an NEID becomes invalid (e.g., resolution returns no results), re-resolve the entity using its canonical name from the previous query result, then redo any downstream operations that depended on it. NEIDs should NEVER be hardcoded in source code.
|
|
6
|
+
|
|
7
|
+
**Looking for property-based search?** To search for entities by type, property values, or relationships using the expression language, see [find.md](find.md).
|
|
8
|
+
|
|
5
9
|
## When to Use
|
|
6
10
|
|
|
7
11
|
- You have an entity name and need to find its NEID
|
|
@@ -16,28 +20,24 @@ Entities are the core objects in the Knowledge Graph: companies, people, organiz
|
|
|
16
20
|
- Example: `00416400910670863867`
|
|
17
21
|
- Always pad with leading zeros to exactly 20 characters when normalizing
|
|
18
22
|
- **EID**: The term EID is sometimes used interchangeably with NEID.
|
|
23
|
+
- **nindex**: The term nindex is sometimes used interchangeably with NEID.
|
|
19
24
|
- **Entity Resolution**: The same real-world entity may have multiple names (e.g., "Apple", "Apple Inc.", "AAPL"). The API resolves these to a single NEID.
|
|
20
|
-
- **Entity Types
|
|
25
|
+
- **Flavors (Entity Types)**: Each entity has a type identified by a Flavor ID (FID).
|
|
21
26
|
|
|
22
27
|
## Tips
|
|
23
28
|
|
|
24
29
|
- Always start by searching for the entity to get the correct NEID
|
|
25
|
-
- After resolving an entity to an NEID,
|
|
30
|
+
- After resolving an entity to an NEID, save and use the the canonical entity name going forward.
|
|
26
31
|
- It's typically safe to resolve an entity to the top matching NEID. However, sometimes a useful pattern is to let the user give input that the resolution was incorrect, show them a longer list of matches, and let them choose a different resolution.
|
|
27
32
|
- Entity names are case-insensitive
|
|
28
33
|
|
|
29
34
|
## Key Endpoints
|
|
30
35
|
|
|
31
|
-
| What you need | Endpoint |
|
|
32
|
-
|
|
33
|
-
| Find
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
| Full property values | `POST /elemental/entities/properties` | `getPropertyValues()` | All properties with PIDs, values, timestamps |
|
|
37
|
-
|
|
38
|
-
**`findEntities()` vs `getNEID()` for entity search**:
|
|
39
|
-
- **`findEntities()`** → `POST /elemental/find` — expression-based search. Supports filtering by type, property value, relationship, and complex nested queries. See `find.md` for the expression language. **Use this for filtered or batch searches.**
|
|
40
|
-
- **`getNEID()`** → `GET /entities/lookup` — simple single-entity name lookup via query parameters (`entityName`, `maxResults`). Best for resolving one company/person name quickly.
|
|
36
|
+
| What you need | Endpoint | Returns |
|
|
37
|
+
|---------------|----------|---------|
|
|
38
|
+
| Find entity by name (batch, scored) | `POST /entities/search` | Ranked matches with NEIDs and scores |
|
|
39
|
+
| Basic info (name, aliases, type) | `GET /entities/{neid}` | Quick summary for display |
|
|
40
|
+
| Full property values | `POST /elemental/entities/properties` | All properties with PIDs, values, timestamps |
|
|
41
41
|
|
|
42
42
|
**Important**: When a user asks for "entity properties," clarify which they mean:
|
|
43
43
|
- Basic info/metadata → use `/entities/{neid}`
|
|
@@ -160,57 +160,42 @@ The same pattern applies to the `expression` parameter on `POST /elemental/find`
|
|
|
160
160
|
|
|
161
161
|
For understanding entity types (flavors), properties, and the data model, see **schema.md**. You'll need the schema because many API responses return only FIDs and PIDs — use it to translate these to human-readable names.
|
|
162
162
|
|
|
163
|
+
## Properties Return Multiple Timestamped Values
|
|
163
164
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
## Endpoints
|
|
167
|
-
|
|
168
|
-
### Get entity details
|
|
169
|
-
|
|
170
|
-
`GET /entities/{neid}`
|
|
171
|
-
|
|
172
|
-
Get details about a named entity including name, aliases, and type. This is an alias for /reports/{neid}. Response is cached for 5 minutes.
|
|
173
|
-
|
|
174
|
-
#### Guidance
|
|
175
|
-
|
|
176
|
-
Response is wrapped in a 'report' container object. Access entity data via response.report.
|
|
177
|
-
|
|
178
|
-
#### Parameters
|
|
179
|
-
|
|
180
|
-
| Name | Type | Required | Description |
|
|
181
|
-
|------|------|----------|-------------|
|
|
182
|
-
| neid | string | yes | Named Entity ID |
|
|
165
|
+
`getPropertyValues` returns **all** recorded values for a property, not just the latest. A single entity and property (e.g. Apple's `company_cik`) may return dozens of rows with different `recorded_at` timestamps — one per filing or data ingestion event. For display, take the first (or latest) value and deduplicate by PID:
|
|
183
166
|
|
|
184
|
-
|
|
167
|
+
```typescript
|
|
168
|
+
const byPid = new Map<number, string>();
|
|
169
|
+
for (const v of values) {
|
|
170
|
+
if (!byPid.has(v.pid)) byPid.set(v.pid, v.value);
|
|
171
|
+
}
|
|
172
|
+
```
|
|
185
173
|
|
|
186
|
-
|
|
187
|
-
|--------|-------------|
|
|
188
|
-
| 200 | Entity details (`GetNamedEntityReportResponse`) |
|
|
189
|
-
| 400 | Invalid NEID (`Error`) |
|
|
190
|
-
| 404 | Entity not found (`Error`) |
|
|
191
|
-
| 500 | Internal server error (`Error`) |
|
|
174
|
+
## `include_attributes` Parameter
|
|
192
175
|
|
|
193
|
-
|
|
176
|
+
`getPropertyValues` accepts an `include_attributes` parameter (set to `'true'` as a string) that returns additional metadata on each value. This is essential for relationship properties like `appears_in`, where attributes carry entity-level sentiment scores and article URLs.
|
|
194
177
|
|
|
195
|
-
**
|
|
178
|
+
**Note:** The generated TypeScript client types don't include `include_attributes` in the parameter type. Pass it as an extra property — the API accepts it:
|
|
196
179
|
|
|
197
|
-
```
|
|
198
|
-
|
|
180
|
+
```typescript
|
|
181
|
+
const res = await client.getPropertyValues({
|
|
182
|
+
eids: JSON.stringify([neid]),
|
|
183
|
+
pids: JSON.stringify([appearsInPid]),
|
|
184
|
+
include_attributes: 'true', // Not in TS types, but API accepts it
|
|
185
|
+
} as any);
|
|
199
186
|
```
|
|
200
187
|
|
|
201
|
-
**
|
|
188
|
+
Attribute values are keyed by **numeric PID**, not by name. Resolve attribute names to PIDs via the schema before accessing them.
|
|
202
189
|
|
|
203
|
-
|
|
204
|
-
{"report": {"neid": "00416400910670863867", "name": "Apple", "aliases": ["AAPL", "APPLE", "APPLE INC", "Apple Inc"], "type": "organization"}}
|
|
205
|
-
```
|
|
190
|
+
<!-- BEGIN GENERATED CONTENT -->
|
|
206
191
|
|
|
207
|
-
|
|
192
|
+
## Endpoints
|
|
208
193
|
|
|
209
|
-
### Get entity
|
|
194
|
+
### Get entity details
|
|
210
195
|
|
|
211
|
-
`GET /
|
|
196
|
+
`GET /entities/{neid}`
|
|
212
197
|
|
|
213
|
-
Get
|
|
198
|
+
Get details about a named entity including name, aliases, and type. This is an alias for /reports/{neid}. Response is cached for 5 minutes.
|
|
214
199
|
|
|
215
200
|
#### Guidance
|
|
216
201
|
|
|
@@ -226,7 +211,7 @@ Response is wrapped in a 'report' container object. Access entity data via respo
|
|
|
226
211
|
|
|
227
212
|
| Status | Description |
|
|
228
213
|
|--------|-------------|
|
|
229
|
-
| 200 | Entity
|
|
214
|
+
| 200 | Entity details (`GetNamedEntityReportResponse`) |
|
|
230
215
|
| 400 | Invalid NEID (`Error`) |
|
|
231
216
|
| 404 | Entity not found (`Error`) |
|
|
232
217
|
| 500 | Internal server error (`Error`) |
|
|
@@ -236,7 +221,7 @@ Response is wrapped in a 'report' container object. Access entity data via respo
|
|
|
236
221
|
**Request:**
|
|
237
222
|
|
|
238
223
|
```
|
|
239
|
-
GET /
|
|
224
|
+
GET /entities/00416400910670863867
|
|
240
225
|
```
|
|
241
226
|
|
|
242
227
|
**Response:**
|
|
@@ -247,54 +232,6 @@ GET /reports/00416400910670863867
|
|
|
247
232
|
|
|
248
233
|
---
|
|
249
234
|
|
|
250
|
-
### Find entities by expression
|
|
251
|
-
|
|
252
|
-
`POST /elemental/find`
|
|
253
|
-
|
|
254
|
-
Search for entities using a powerful expression language. The expression parameter supports complex nested queries with logical operators, geographic constraints, property comparisons, and more.
|
|
255
|
-
|
|
256
|
-
#### Guidance
|
|
257
|
-
|
|
258
|
-
CRITICAL: This endpoint REQUIRES Content-Type: application/x-www-form-urlencoded. Sending a JSON body will fail with 400 error. The expression parameter must be URL-encoded form data, not a JSON request body. For the full expression language reference including all expression types, comparison operators, and examples, see find.md.
|
|
259
|
-
|
|
260
|
-
#### Request Body
|
|
261
|
-
|
|
262
|
-
**Content-Type:** `application/x-www-form-urlencoded`
|
|
263
|
-
|
|
264
|
-
| Name | Type | Required | Description |
|
|
265
|
-
|------|------|----------|-------------|
|
|
266
|
-
| expression | string | yes | JSON-encoded expression object defining the search criteria |
|
|
267
|
-
| deadline | any | no | Response deadline in milliseconds or duration format |
|
|
268
|
-
| limit | integer | no | Maximum number of entity IDs to return in first response |
|
|
269
|
-
|
|
270
|
-
#### Responses
|
|
271
|
-
|
|
272
|
-
| Status | Description |
|
|
273
|
-
|--------|-------------|
|
|
274
|
-
| 200 | Find operation successful (`FindResponse`) |
|
|
275
|
-
| 400 | Bad request - invalid parameters or malformed expression (`Error`) |
|
|
276
|
-
| 500 | Internal server error (`Error`) |
|
|
277
|
-
| 501 | Elemental API capability not enabled (`Error`) |
|
|
278
|
-
|
|
279
|
-
#### Example
|
|
280
|
-
|
|
281
|
-
**Request:**
|
|
282
|
-
|
|
283
|
-
```
|
|
284
|
-
POST /elemental/find
|
|
285
|
-
Content-Type: application/x-www-form-urlencoded
|
|
286
|
-
|
|
287
|
-
expression={"type":"is_type","is_type":{"fid":10}}&limit=5
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
**Response:**
|
|
291
|
-
|
|
292
|
-
```json
|
|
293
|
-
{"op_id": "98cc54e9-0108-4361-9c96-18ea97cda7a2", "follow_up": true, "eids": ["01601807036815568643", "08115040994665529432", "02045070050429461063"]}
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
235
|
### Get property values for entities
|
|
299
236
|
|
|
300
237
|
`POST /elemental/entities/properties`
|
|
@@ -361,18 +298,6 @@ The named entity report
|
|
|
361
298
|
| neid | string | Named Entity ID |
|
|
362
299
|
| type | string | Entity type (flavor) |
|
|
363
300
|
|
|
364
|
-
### FindResponse
|
|
365
|
-
|
|
366
|
-
| Field | Type | Description |
|
|
367
|
-
|-------|------|-------------|
|
|
368
|
-
| find | `FindData` | |
|
|
369
|
-
|
|
370
|
-
### FindData
|
|
371
|
-
|
|
372
|
-
| Field | Type | Description |
|
|
373
|
-
|-------|------|-------------|
|
|
374
|
-
| **eids** | string[] | Array of 20-character entity IDs matching the search expression |
|
|
375
|
-
|
|
376
301
|
### GetPropertyValuesResponse
|
|
377
302
|
|
|
378
303
|
| Field | Type | Description |
|
|
@@ -5,8 +5,8 @@ The `/elemental/find` endpoint searches for entities using a JSON expression lan
|
|
|
5
5
|
## When to Use
|
|
6
6
|
|
|
7
7
|
- You need to search for entities matching specific criteria (type, property values, relationships)
|
|
8
|
-
- You need to combine multiple filters
|
|
9
|
-
- You need to find entities connected to a given entity via the
|
|
8
|
+
- You need to combine multiple filters
|
|
9
|
+
- You need to find entities connected to a given entity via the relationship links
|
|
10
10
|
|
|
11
11
|
## Expression Structure
|
|
12
12
|
|
|
@@ -124,13 +124,13 @@ Content-Type: application/x-www-form-urlencoded
|
|
|
124
124
|
expression={"type":"comparison","comparison":{"operator":"string_like","pid":8,"value":"Apple"}}
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
### Find
|
|
127
|
+
### Find organizations with "Global" in the name (combined AND)
|
|
128
128
|
|
|
129
129
|
```
|
|
130
130
|
POST /elemental/find
|
|
131
131
|
Content-Type: application/x-www-form-urlencoded
|
|
132
132
|
|
|
133
|
-
expression={"type":"and","and":[{"type":"is_type","is_type":{"fid":
|
|
133
|
+
expression={"type":"and","and":[{"type":"is_type","is_type":{"fid":10}},{"type":"comparison","comparison":{"operator":"string_like","pid":8,"value":"Global"}}]}&limit=50
|
|
134
134
|
```
|
|
135
135
|
|
|
136
136
|
### Find entities linked to a specific entity
|
|
@@ -261,6 +261,12 @@ expression={"type":"is_type","is_type":{"fid":10}}&limit=5
|
|
|
261
261
|
|-------|------|-------------|
|
|
262
262
|
| **is_type** | `IsType` | |
|
|
263
263
|
|
|
264
|
+
### LinkedExpression
|
|
265
|
+
|
|
266
|
+
| Field | Type | Description |
|
|
267
|
+
|-------|------|-------------|
|
|
268
|
+
| **linked** | `Linked` | |
|
|
269
|
+
|
|
264
270
|
### Comparison
|
|
265
271
|
|
|
266
272
|
| Field | Type | Description |
|
|
@@ -276,4 +282,13 @@ expression={"type":"is_type","is_type":{"fid":10}}&limit=5
|
|
|
276
282
|
|-------|------|-------------|
|
|
277
283
|
| **fid** | integer | Flavor identifier (FID) representing entity type |
|
|
278
284
|
|
|
285
|
+
### Linked
|
|
286
|
+
|
|
287
|
+
| Field | Type | Description |
|
|
288
|
+
|-------|------|-------------|
|
|
289
|
+
| **distance** | integer | Maximum relationship distance to traverse |
|
|
290
|
+
| pids | integer[] | Property identifiers defining the relationship types to follow |
|
|
291
|
+
| to_entity | string | Target entity ID for relationship traversal |
|
|
292
|
+
| direction | string | Direction of relationship traversal. 'outgoing' (default) follows subject->value edges, 'incoming' follows value->subject (reverse) edges, 'both' unions outgoing and incoming results. |
|
|
293
|
+
|
|
279
294
|
<!-- END GENERATED CONTENT -->
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Graph
|
|
2
2
|
|
|
3
|
-
The graph endpoints are focused on "graph analysis"
|
|
3
|
+
The graph endpoints are focused on "graph analysis". This includes, but is not limited to, visual rendering of a graph.
|
|
4
4
|
|
|
5
5
|
## When to Use
|
|
6
6
|
|
|
@@ -32,7 +32,7 @@ Get nodes and edges layout data for visualizing a relationship graph. Response i
|
|
|
32
32
|
|
|
33
33
|
#### Guidance
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
This should always be called with a non-empty list of neids. A typical pattern is to call /graph/{center_neid}/neighborhood and then use the returned NEIDs to call this endpoint.
|
|
36
36
|
|
|
37
37
|
#### Parameters
|
|
38
38
|
|
|
@@ -77,7 +77,7 @@ Get list of neighboring entities in the relationship graph, optionally filtered
|
|
|
77
77
|
|
|
78
78
|
#### Guidance
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
Response includes the center entity itself in the results with a weight of 1.0. The 'neighbors' and 'weights' arrays are parallel (same indices correspond).
|
|
81
81
|
|
|
82
82
|
#### Parameters
|
|
83
83
|
|
|
@@ -4,26 +4,55 @@ The Elemental API provides access to the Lovelace Knowledge Graph through the Qu
|
|
|
4
4
|
|
|
5
5
|
## Core Concepts
|
|
6
6
|
|
|
7
|
-
###
|
|
7
|
+
### Entities
|
|
8
|
+
|
|
9
|
+
Every entity has:
|
|
10
|
+
- **NEID** — a unique Named Entity ID (stable identifier)
|
|
11
|
+
- **Name** — human-readable label (may have aliases)
|
|
12
|
+
- **Flavor** — the entity type (e.g. "organization", "person", "country", "vessel", "event")
|
|
13
|
+
|
|
14
|
+
#### Named Entity ID (NEID)
|
|
15
|
+
|
|
8
16
|
Every entity in the system has a unique identifier called a NEID. Most API calls require a NEID, so your first step is usually looking up an entity by name to get its NEID.
|
|
9
17
|
|
|
10
18
|
**Format**: 20-character numeric string with zero-padding. Example: `00416400910670863867`
|
|
11
19
|
|
|
12
20
|
When normalizing NEIDs, always pad with leading zeros to exactly 20 characters.
|
|
13
21
|
|
|
22
|
+
NEIDs are stable and can be persisted long-term, but may occasionally change if the database is rebuilt or the application switches databases. When an NEID becomes invalid (e.g., resolution returns no results), re-resolve the entity using its canonical name from the previous query result, then redo any downstream operations that depended on it. NEIDs should NEVER be hardcoded in source code.
|
|
23
|
+
|
|
14
24
|
**Note**: The terms "eid" and "neid" are interchangeable throughout the API. Some endpoints use `neid` and others use `eid`, but they refer to the same entity identifier.
|
|
15
25
|
|
|
16
|
-
###
|
|
17
|
-
|
|
26
|
+
### Properties
|
|
27
|
+
|
|
28
|
+
Key-value facts attached to entities, scoped by flavor.
|
|
29
|
+
|
|
30
|
+
Examples: nationality, birth_date, industry, total_revenue, employee_count.
|
|
31
|
+
|
|
32
|
+
Use the schema to discover which properties are available for
|
|
33
|
+
a given entity type.
|
|
18
34
|
|
|
19
|
-
|
|
35
|
+
## Relationships
|
|
20
36
|
|
|
21
|
-
|
|
22
|
-
|
|
37
|
+
Directed, typed edges between two entities:
|
|
38
|
+
- **Type** — e.g. "owns", "board_member_of", "subsidiary_of", "appears_in"
|
|
39
|
+
- **Direction** — relationships go from source (subject) to target (object)
|
|
23
40
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
41
|
+
## Attributes
|
|
42
|
+
|
|
43
|
+
Metadata attached to relationships. For example, the "participant" relationship
|
|
44
|
+
connecting an entity to an event carries:
|
|
45
|
+
- **role** — the entity's role in the event (e.g. "acquirer", "target", "plaintiff")
|
|
46
|
+
- **sentiment** — an impact score for the entity's involvement
|
|
47
|
+
|
|
48
|
+
## Events
|
|
49
|
+
|
|
50
|
+
Structured occurrences extracted from source data, each with:
|
|
51
|
+
- **Category** — e.g. "Bankruptcy", "IPO", "Layoffs", "Acquisition"
|
|
52
|
+
- **Date** — when the event occurred (YYYY-MM-DD, or YYYY-MM / YYYY for partial dates)
|
|
53
|
+
- **Description** — detailed, objective description of the event
|
|
54
|
+
- **Likelihood** — temporal status: confirmed, ongoing, likely, or speculative
|
|
55
|
+
- **Participants** — entities involved, each with a role and sentiment score
|
|
27
56
|
|
|
28
57
|
## Endpoint Categories
|
|
29
58
|
|
|
@@ -31,21 +60,16 @@ Most endpoints accept `start` and `end` parameters for filtering by date.
|
|
|
31
60
|
|------|------------------------|
|
|
32
61
|
| [entities.md](entities.md) | Look up entities by name, get details and properties |
|
|
33
62
|
| [find.md](find.md) | Search for entities by type, property values, or relationships using the expression language |
|
|
34
|
-
| [
|
|
35
|
-
| [articles.md](articles.md) | Get articles that mention an entity, article content, titles, summaries |
|
|
36
|
-
| [events.md](events.md) | Find events involving an entity (mergers, lawsuits, etc.) |
|
|
37
|
-
| [relationships.md](relationships.md) | Find connections between entities |
|
|
63
|
+
| [schema.md](schema.md) | Understand the data model: entity types (flavors), properties, and their metadata |
|
|
38
64
|
| [graph.md](graph.md) | Generate visual network graphs |
|
|
39
|
-
| [server.md](server.md) | Check server status and capabilities
|
|
40
|
-
| [llm.md](llm.md) | (Not currently available) AI-assisted queries |
|
|
65
|
+
| [server.md](server.md) | Check server status and capabilities |
|
|
41
66
|
|
|
42
67
|
## Common Workflows
|
|
43
68
|
|
|
44
|
-
### "
|
|
45
|
-
1. `
|
|
46
|
-
2. `
|
|
47
|
-
|
|
69
|
+
### "Find all organizations in a specific sector"
|
|
70
|
+
1. `schema.md` → Check available properties and flavors
|
|
71
|
+
2. `find.md` → Use the expression language to search by property values
|
|
48
72
|
|
|
49
|
-
### "
|
|
50
|
-
1. `entities.md` → Look up
|
|
51
|
-
2. `
|
|
73
|
+
### "What companies are related to Apple?"
|
|
74
|
+
1. `entities.md` → Look up "Apple" to get NEID
|
|
75
|
+
2. `find.md` → Query linked entities to find related entities
|