@props-labs/mesh-os 0.1.20 → 0.2.0

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 (44) hide show
  1. package/dist/core/__fixtures__/mock_responses.d.ts +318 -0
  2. package/dist/core/__fixtures__/mock_responses.js +333 -0
  3. package/dist/core/__fixtures__/sample_embeddings.d.ts +33 -0
  4. package/dist/core/__fixtures__/sample_embeddings.js +12355 -0
  5. package/dist/core/agents.d.ts +51 -0
  6. package/dist/core/agents.js +170 -0
  7. package/dist/core/client.d.ts +3 -1
  8. package/dist/core/client.js +10 -34
  9. package/dist/core/memories.d.ts +138 -0
  10. package/dist/core/memories.js +417 -0
  11. package/dist/core/taxonomy.d.ts +44 -0
  12. package/dist/core/taxonomy.js +25 -1
  13. package/dist/core/workflows.d.ts +104 -0
  14. package/dist/core/workflows.js +332 -0
  15. package/package.json +3 -3
  16. package/src/templates/hasura/metadata/actions.yaml +6 -0
  17. package/src/templates/hasura/metadata/cron_triggers.yaml +1 -0
  18. package/src/templates/hasura/metadata/databases/databases.yaml +1 -1
  19. package/src/templates/hasura/metadata/databases/default/functions/functions.yaml +80 -0
  20. package/src/templates/hasura/metadata/databases/default/tables/tables.yaml +274 -9
  21. package/src/templates/hasura/metadata/query_collections.yaml +1 -0
  22. package/src/templates/hasura/metadata/rest_endpoints.yaml +1 -0
  23. package/src/templates/hasura/migrations/default/0_cleanup/down.sql +2 -0
  24. package/src/templates/hasura/migrations/default/0_cleanup/up.sql +59 -0
  25. package/src/templates/hasura/migrations/default/1_init/down.sql +27 -21
  26. package/src/templates/hasura/migrations/default/1_init/up.sql +446 -174
  27. package/src/templates/hasura/migrations/default/2_sample_data/down.sql +3 -0
  28. package/src/templates/hasura/migrations/default/2_sample_data/up.sql +288 -0
  29. package/src/templates/hasura/migrations/default/3_agent_relations/down.sql +76 -0
  30. package/src/templates/hasura/migrations/default/3_agent_relations/up.sql +469 -0
  31. package/src/templates/hasura/metadata/config.yaml +0 -1
  32. package/src/templates/hasura/metadata/databases/default/tables/public_agents.yaml +0 -14
  33. package/src/templates/hasura/metadata/databases/default/tables/public_memories.yaml +0 -23
  34. package/src/templates/hasura/metadata/databases/default/tables/public_memory_edges.yaml +0 -57
  35. package/src/templates/hasura/metadata/databases/default/tables/track_tables.yaml +0 -14
  36. package/src/templates/hasura/metadata/metadata.json +0 -80
  37. package/src/templates/hasura/migrations/default/2_metadata_filtering/down.sql +0 -4
  38. package/src/templates/hasura/migrations/default/2_metadata_filtering/up.sql +0 -44
  39. package/src/templates/hasura/migrations/default/3_memory_expiry/down.sql +0 -55
  40. package/src/templates/hasura/migrations/default/3_memory_expiry/up.sql +0 -108
  41. package/src/templates/hasura/migrations/default/4_remove_slug_validation/down.sql +0 -20
  42. package/src/templates/hasura/migrations/default/4_remove_slug_validation/up.sql +0 -5
  43. package/src/templates/hasura/migrations/default/5_entities/down.sql +0 -13
  44. package/src/templates/hasura/migrations/default/5_entities/up.sql +0 -155
@@ -0,0 +1,51 @@
1
+ export interface Agent {
2
+ id: string;
3
+ name: string | null;
4
+ description: string | null;
5
+ slug: string | null;
6
+ created_at: string;
7
+ updated_at: string;
8
+ }
9
+ export interface CreateAgentInput {
10
+ name?: string | null;
11
+ description?: string | null;
12
+ }
13
+ export interface UpdateAgentInput {
14
+ id: string;
15
+ name?: string | null;
16
+ description?: string | null;
17
+ }
18
+ export interface RegisterAgentInput {
19
+ name?: string | null;
20
+ description?: string | null;
21
+ slug?: string | null;
22
+ }
23
+ export declare class InvalidSlugError extends Error {
24
+ constructor(message: string);
25
+ }
26
+ export declare class AgentManager {
27
+ private url;
28
+ private headers;
29
+ constructor(url: string, headers: Record<string, string>);
30
+ private validateSlug;
31
+ /**
32
+ * Execute a GraphQL query against Hasura
33
+ */
34
+ private executeQuery;
35
+ /**
36
+ * Get an agent by slug
37
+ */
38
+ getBySlug(slug: string): Promise<Agent | null>;
39
+ /**
40
+ * Register a new agent or return existing one if slug exists
41
+ */
42
+ register(input: RegisterAgentInput): Promise<Agent>;
43
+ /**
44
+ * Get an agent by ID
45
+ */
46
+ get(id: string): Promise<Agent>;
47
+ /**
48
+ * Update an agent
49
+ */
50
+ update(input: UpdateAgentInput): Promise<Agent>;
51
+ }
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgentManager = exports.InvalidSlugError = void 0;
4
+ const zod_1 = require("zod");
5
+ // Validation schemas
6
+ const agentSchema = zod_1.z.object({
7
+ id: zod_1.z.string().uuid(),
8
+ name: zod_1.z.string().nullable(),
9
+ description: zod_1.z.string().nullable(),
10
+ slug: zod_1.z.string().nullable(),
11
+ created_at: zod_1.z.string(),
12
+ updated_at: zod_1.z.string()
13
+ });
14
+ // Slug pattern for validation
15
+ const SLUG_PATTERN = /^[a-zA-Z0-9_-]+$/;
16
+ class InvalidSlugError extends Error {
17
+ constructor(message) {
18
+ super(message);
19
+ this.name = 'InvalidSlugError';
20
+ }
21
+ }
22
+ exports.InvalidSlugError = InvalidSlugError;
23
+ class AgentManager {
24
+ constructor(url, headers) {
25
+ this.url = url;
26
+ this.headers = headers;
27
+ }
28
+ validateSlug(slug) {
29
+ return SLUG_PATTERN.test(slug);
30
+ }
31
+ /**
32
+ * Execute a GraphQL query against Hasura
33
+ */
34
+ async executeQuery(query, variables) {
35
+ const response = await fetch(this.url, {
36
+ method: 'POST',
37
+ headers: {
38
+ 'Content-Type': 'application/json',
39
+ ...this.headers
40
+ },
41
+ body: JSON.stringify({
42
+ query,
43
+ variables
44
+ })
45
+ });
46
+ if (!response.ok) {
47
+ throw new Error(`Failed to execute query: ${response.statusText}`);
48
+ }
49
+ const result = (await response.json());
50
+ if (result.errors) {
51
+ throw new Error(`GraphQL error: ${result.errors[0].message}`);
52
+ }
53
+ return result.data;
54
+ }
55
+ /**
56
+ * Get an agent by slug
57
+ */
58
+ async getBySlug(slug) {
59
+ if (!this.validateSlug(slug)) {
60
+ throw new InvalidSlugError("Slug must contain only URL-safe characters (letters, numbers, hyphens, and underscores)");
61
+ }
62
+ const query = `
63
+ query GetAgentBySlug($slug: String!) {
64
+ agents(where: {slug: {_eq: $slug}}, limit: 1) {
65
+ id
66
+ name
67
+ description
68
+ slug
69
+ created_at
70
+ updated_at
71
+ }
72
+ }
73
+ `;
74
+ const result = await this.executeQuery(query, { slug });
75
+ return result.agents[0] ? agentSchema.parse(result.agents[0]) : null;
76
+ }
77
+ /**
78
+ * Register a new agent or return existing one if slug exists
79
+ */
80
+ async register(input) {
81
+ if (input.slug) {
82
+ if (!this.validateSlug(input.slug)) {
83
+ throw new InvalidSlugError("Slug must contain only URL-safe characters (letters, numbers, hyphens, and underscores)");
84
+ }
85
+ // Check for existing agent with this slug
86
+ const existing = await this.getBySlug(input.slug);
87
+ if (existing) {
88
+ return existing;
89
+ }
90
+ }
91
+ const query = `
92
+ mutation RegisterAgent($agent: agents_insert_input!) {
93
+ insert_agents_one(object: $agent) {
94
+ id
95
+ name
96
+ description
97
+ slug
98
+ created_at
99
+ updated_at
100
+ }
101
+ }
102
+ `;
103
+ const result = await this.executeQuery(query, {
104
+ agent: {
105
+ name: input.name,
106
+ description: input.description,
107
+ slug: input.slug
108
+ }
109
+ });
110
+ return agentSchema.parse(result.insert_agents_one);
111
+ }
112
+ /**
113
+ * Get an agent by ID
114
+ */
115
+ async get(id) {
116
+ const query = `
117
+ query GetAgent($id: uuid!) {
118
+ agents_by_pk(id: $id) {
119
+ id
120
+ name
121
+ description
122
+ slug
123
+ created_at
124
+ updated_at
125
+ }
126
+ }
127
+ `;
128
+ const result = await this.executeQuery(query, { id });
129
+ const agent = result.agents_by_pk;
130
+ if (!agent) {
131
+ throw new Error(`Agent not found with id: ${id}`);
132
+ }
133
+ return agentSchema.parse(agent);
134
+ }
135
+ /**
136
+ * Update an agent
137
+ */
138
+ async update(input) {
139
+ // First verify the agent exists
140
+ await this.get(input.id);
141
+ // Prepare update object with only changed fields
142
+ const updateFields = {};
143
+ if (input.name !== undefined)
144
+ updateFields.name = input.name;
145
+ if (input.description !== undefined)
146
+ updateFields.description = input.description;
147
+ // If no fields to update, return existing agent
148
+ if (Object.keys(updateFields).length === 0) {
149
+ return this.get(input.id);
150
+ }
151
+ const query = `
152
+ mutation UpdateAgent($id: uuid!, $updates: agents_set_input!) {
153
+ update_agents_by_pk(pk_columns: {id: $id}, _set: $updates) {
154
+ id
155
+ name
156
+ description
157
+ slug
158
+ created_at
159
+ updated_at
160
+ }
161
+ }
162
+ `;
163
+ const result = await this.executeQuery(query, {
164
+ id: input.id,
165
+ updates: updateFields
166
+ });
167
+ return agentSchema.parse(result.update_agents_by_pk);
168
+ }
169
+ }
170
+ exports.AgentManager = AgentManager;
@@ -1,5 +1,6 @@
1
1
  import { EdgeType, type AgentStatus, type EdgeMetadata, type MemoryMetadata, type TimestampFilter, EntityRelationshipType } from './taxonomy';
2
2
  import { EntityManager } from './entities';
3
+ import { WorkflowManager } from './workflows';
3
4
  /**
4
5
  * An agent in the system.
5
6
  */
@@ -76,6 +77,7 @@ export declare class MeshOS {
76
77
  private headers;
77
78
  private openai;
78
79
  entities: EntityManager;
80
+ workflows: WorkflowManager;
79
81
  constructor(config?: MeshOSConfig);
80
82
  private validateSlug;
81
83
  /**
@@ -117,7 +119,7 @@ export declare class MeshOS {
117
119
  /**
118
120
  * Create a link between two memories.
119
121
  */
120
- linkMemories(sourceMemoryId: string, targetMemoryId: string, relationship: EdgeType, weight?: number, metadata?: Partial<EdgeMetadata>): Promise<MemoryEdge>;
122
+ linkMemories(sourceMemoryId: string, targetMemoryId: string, relationship: EdgeType, weight?: number): Promise<MemoryEdge>;
121
123
  /**
122
124
  * Remove links between two memories.
123
125
  */
@@ -12,6 +12,7 @@ const chalk_1 = __importDefault(require("chalk"));
12
12
  const boxen_1 = __importDefault(require("boxen"));
13
13
  const taxonomy_1 = require("./taxonomy");
14
14
  const entities_1 = require("./entities");
15
+ const workflows_1 = require("./workflows");
15
16
  // Constants
16
17
  const SLUG_PATTERN = /^[a-zA-Z0-9_-]+$/;
17
18
  /**
@@ -61,8 +62,9 @@ class MeshOS {
61
62
  throw new Error('OpenAI API key is required');
62
63
  }
63
64
  this.openai = new openai_1.default({ apiKey: openaiApiKey });
64
- // Initialize entity manager
65
+ // Initialize managers
65
66
  this.entities = new entities_1.EntityManager(this.url, this.headers, this.createEmbedding.bind(this));
67
+ this.workflows = new workflows_1.WorkflowManager(this.url, this.headers);
66
68
  }
67
69
  validateSlug(slug) {
68
70
  return SLUG_PATTERN.test(slug);
@@ -339,19 +341,9 @@ class MeshOS {
339
341
  memories.push(memory);
340
342
  // Link chunks sequentially
341
343
  if (previousChunkId) {
342
- await this.linkMemories(previousChunkId, memory.id, taxonomy_1.EdgeType.FOLLOWS_UP, 1.0, {
343
- relationship: taxonomy_1.EdgeType.FOLLOWS_UP,
344
- weight: 1.0,
345
- bidirectional: false,
346
- additional: { is_chunk_link: true }
347
- });
344
+ await this.linkMemories(previousChunkId, memory.id, taxonomy_1.EdgeType.FOLLOWS_UP, 1.0);
348
345
  // Also add PART_OF relationship to show these are parts of the same content
349
- await this.linkMemories(memory.id, previousChunkId, taxonomy_1.EdgeType.PART_OF, 1.0, {
350
- relationship: taxonomy_1.EdgeType.PART_OF,
351
- weight: 1.0,
352
- bidirectional: true,
353
- additional: { is_chunk_link: true }
354
- });
346
+ await this.linkMemories(memory.id, previousChunkId, taxonomy_1.EdgeType.PART_OF, 1.0);
355
347
  }
356
348
  previousChunkId = memory.id;
357
349
  }
@@ -376,21 +368,19 @@ class MeshOS {
376
368
  /**
377
369
  * Create a link between two memories.
378
370
  */
379
- async linkMemories(sourceMemoryId, targetMemoryId, relationship, weight = 1.0, metadata) {
371
+ async linkMemories(sourceMemoryId, targetMemoryId, relationship, weight = 1.0) {
380
372
  const query = `
381
373
  mutation LinkMemories(
382
374
  $sourceMemory: uuid!,
383
375
  $targetMemory: uuid!,
384
376
  $relationship: String!,
385
- $weight: float8!,
386
- $metadata: jsonb!
377
+ $weight: float8!
387
378
  ) {
388
379
  insert_memory_edges_one(object: {
389
380
  source_memory: $sourceMemory,
390
381
  target_memory: $targetMemory,
391
382
  relationship: $relationship,
392
- weight: $weight,
393
- metadata: $metadata
383
+ weight: $weight
394
384
  }) {
395
385
  id
396
386
  source_memory
@@ -398,23 +388,14 @@ class MeshOS {
398
388
  relationship
399
389
  weight
400
390
  created_at
401
- metadata
402
391
  }
403
392
  }
404
393
  `;
405
- const fullMetadata = {
406
- relationship,
407
- weight,
408
- bidirectional: false,
409
- additional: {},
410
- ...metadata
411
- };
412
394
  const result = await this.executeQuery(query, {
413
395
  sourceMemory: sourceMemoryId,
414
396
  targetMemory: targetMemoryId,
415
397
  relationship,
416
- weight,
417
- metadata: fullMetadata
398
+ weight
418
399
  });
419
400
  // Convert snake_case to camelCase
420
401
  const { source_memory, target_memory, created_at, ...rest } = result.insert_memory_edges_one;
@@ -484,12 +465,7 @@ class MeshOS {
484
465
  if (createVersionEdge) {
485
466
  // If we got multiple memories (chunks), link the first one
486
467
  const firstNewMemory = Array.isArray(newMemories) ? newMemories[0] : newMemories;
487
- await this.linkMemories(oldMemory.id, firstNewMemory.id, taxonomy_1.EdgeType.VERSION_OF, 1.0, {
488
- relationship: taxonomy_1.EdgeType.VERSION_OF,
489
- weight: 1.0,
490
- bidirectional: false,
491
- additional: { version_increment: 1 }
492
- });
468
+ await this.linkMemories(oldMemory.id, firstNewMemory.id, taxonomy_1.EdgeType.VERSION_OF, 1.0);
493
469
  }
494
470
  return newMemories;
495
471
  }
@@ -0,0 +1,138 @@
1
+ export interface Memory {
2
+ id: string;
3
+ type: string;
4
+ status: 'active' | 'archived' | 'deleted';
5
+ metadata: Record<string, any>;
6
+ content: string;
7
+ created_at: string;
8
+ updated_at: string;
9
+ agent_id?: string | null;
10
+ }
11
+ export interface MemoryChunk {
12
+ id: string;
13
+ memory_id: string;
14
+ chunk_index: number;
15
+ content: string;
16
+ embedding?: number[];
17
+ metadata: Record<string, any>;
18
+ created_at: string;
19
+ updated_at: string;
20
+ agent_id?: string | null;
21
+ }
22
+ export interface MemoryEdge {
23
+ id: string;
24
+ source_memory: string;
25
+ target_memory: string;
26
+ type: string;
27
+ metadata: Record<string, any>;
28
+ weight: number;
29
+ created_at: string;
30
+ updated_at: string;
31
+ agent_id?: string;
32
+ }
33
+ export interface TypeSchema {
34
+ type: string;
35
+ schema: Record<string, any>;
36
+ metadata_schema?: Record<string, any> | null;
37
+ embedding_config?: {
38
+ model: string;
39
+ dimensions: number;
40
+ } | null;
41
+ chunking_config?: {
42
+ chunk_size: number;
43
+ chunk_overlap: number;
44
+ } | null;
45
+ validation_rules?: Record<string, any> | null;
46
+ behaviors?: Record<string, any> | null;
47
+ created_at: string;
48
+ updated_at: string;
49
+ }
50
+ export interface CreateMemoryInput {
51
+ type: string;
52
+ content: string;
53
+ metadata?: Record<string, any>;
54
+ agent_id?: string;
55
+ }
56
+ export interface CreateMemoryResult {
57
+ memory: Memory;
58
+ chunkCount: number;
59
+ }
60
+ export interface SearchMemoryResult {
61
+ id: string;
62
+ type: string;
63
+ status: string;
64
+ content: string;
65
+ metadata: Record<string, any>;
66
+ created_at: string;
67
+ updated_at: string;
68
+ agent_id?: string;
69
+ similarity: number;
70
+ }
71
+ export interface SearchMemoryOptions {
72
+ query: string;
73
+ threshold?: number;
74
+ limit?: number;
75
+ agentId?: string;
76
+ metadataFilter?: Record<string, any>;
77
+ createdAtFilter?: Record<string, any>;
78
+ }
79
+ export interface UpdateMemoryInput {
80
+ id: string;
81
+ content?: string;
82
+ metadata?: Record<string, any>;
83
+ status?: 'active' | 'archived' | 'deleted';
84
+ }
85
+ export interface UpdateMemoryResult {
86
+ memory: Memory;
87
+ chunkCount?: number;
88
+ }
89
+ export declare class MemoryManager {
90
+ private url;
91
+ private headers;
92
+ private createEmbedding;
93
+ constructor(url: string, headers: Record<string, string>, createEmbedding: (text: string) => Promise<number[]>);
94
+ /**
95
+ * Execute a GraphQL query against Hasura
96
+ */
97
+ private executeQuery;
98
+ /**
99
+ * Get a memory by its ID
100
+ */
101
+ get(id: string): Promise<Memory>;
102
+ /**
103
+ * Get a type schema by its type name
104
+ */
105
+ getTypeSchema(type: string): Promise<TypeSchema>;
106
+ /**
107
+ * Create chunks from content based on type schema configuration
108
+ */
109
+ private createChunks;
110
+ /**
111
+ * Create a new memory with chunks and embeddings
112
+ */
113
+ create(input: CreateMemoryInput): Promise<CreateMemoryResult>;
114
+ /**
115
+ * Search memories by semantic similarity using chunk embeddings
116
+ */
117
+ search(options: SearchMemoryOptions): Promise<SearchMemoryResult[]>;
118
+ /**
119
+ * Clean up test memories and their chunks
120
+ */
121
+ cleanup(memoryIds: string[]): Promise<void>;
122
+ /**
123
+ * Update an existing memory and optionally its chunks
124
+ */
125
+ update(input: UpdateMemoryInput): Promise<UpdateMemoryResult>;
126
+ /**
127
+ * Mark a memory as deleted
128
+ */
129
+ delete(id: string): Promise<Memory>;
130
+ /**
131
+ * Mark a memory as archived
132
+ */
133
+ archive(id: string): Promise<Memory>;
134
+ /**
135
+ * List all available type schemas
136
+ */
137
+ listSchemas(): Promise<TypeSchema[]>;
138
+ }