@elevasis/core 0.1.0 → 0.2.1

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 (35) hide show
  1. package/dist/index.js +195 -3
  2. package/dist/organization-model/index.js +195 -3
  3. package/package.json +1 -1
  4. package/src/README.md +24 -17
  5. package/src/__tests__/template-foundations-compatibility.test.ts +95 -14
  6. package/src/auth/multi-tenancy/types.ts +2 -1
  7. package/src/execution/engine/__tests__/fixtures/test-agents.ts +4 -4
  8. package/src/execution/engine/index.ts +5 -19
  9. package/src/execution/engine/tools/platform/index.ts +9 -33
  10. package/src/execution/engine/tools/registry.ts +109 -2
  11. package/src/execution/engine/tools/tool-maps.ts +88 -0
  12. package/src/organization-model/README.md +19 -4
  13. package/src/organization-model/__tests__/graph.test.ts +612 -0
  14. package/src/organization-model/__tests__/resolve.test.ts +208 -0
  15. package/src/organization-model/defaults.ts +1 -1
  16. package/src/organization-model/organization-graph.mdx +262 -0
  17. package/src/organization-model/organization-model.mdx +257 -0
  18. package/src/organization-model/resolve.ts +26 -2
  19. package/src/organization-model/schema.ts +203 -1
  20. package/src/platform/constants/versions.ts +1 -1
  21. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +24 -0
  22. package/src/platform/registry/__tests__/resource-registry.test.ts +63 -0
  23. package/src/platform/registry/resource-registry.ts +98 -10
  24. package/src/projects/api-schemas.ts +2 -1
  25. package/src/reference/_generated/contracts.md +1044 -0
  26. package/src/reference/glossary.md +88 -0
  27. package/src/server.ts +2 -3
  28. package/src/execution/engine/tools/platform/resource-invocation/__tests__/edge-cases.test.ts +0 -507
  29. package/src/execution/engine/tools/platform/resource-invocation/__tests__/resource-invocation-service.test.ts +0 -500
  30. package/src/execution/engine/tools/platform/resource-invocation/__tests__/tool.test.ts +0 -555
  31. package/src/execution/engine/tools/platform/resource-invocation/dynamic-tool.ts +0 -94
  32. package/src/execution/engine/tools/platform/resource-invocation/index.ts +0 -14
  33. package/src/execution/engine/tools/platform/resource-invocation/resource-invocation-service.ts +0 -147
  34. package/src/execution/engine/tools/platform/resource-invocation/tool.ts +0 -115
  35. package/src/execution/engine/tools/platform/resource-invocation/types.ts +0 -31
@@ -1,500 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest'
2
- import { z } from 'zod'
3
- import { ResourceInvocationService, createResourceInvocationService } from '../resource-invocation-service'
4
- import type { ResourceRegistry } from '../../../../../../platform/registry/resource-registry'
5
- import type { WorkflowDefinition } from '../../../../workflow/types'
6
- import type { AgentDefinition } from '../../../../agent/core/types'
7
- import type { ResourceInvocationResult, ExecuteResourceCallback } from '../types'
8
- import { createMockExecutionContext } from '../../../../test-utils/mocks'
9
-
10
- describe('ResourceInvocationService', () => {
11
- // Mock data
12
- const mockContext = createMockExecutionContext({
13
- organizationId: 'org-123',
14
- organizationName: 'test-org',
15
- executionId: 'exec-456',
16
- resourceId: 'parent-agent',
17
- executionDepth: 0
18
- })
19
-
20
- const mockWorkflowDefinition: WorkflowDefinition = {
21
- config: {
22
- resourceId: 'validation-workflow',
23
- name: 'Validation Workflow',
24
- description: 'Validates data',
25
- version: '1.0.0',
26
- type: 'workflow',
27
- status: 'dev'
28
- },
29
- contract: {
30
- inputSchema: z.object({
31
- email: z.string().email(),
32
- name: z.string()
33
- }),
34
- outputSchema: z.object({
35
- valid: z.boolean(),
36
- errors: z.array(z.string())
37
- })
38
- },
39
- entryPoint: 'validate',
40
- steps: {}
41
- }
42
-
43
- const mockAgentDefinition: AgentDefinition = {
44
- config: {
45
- resourceId: 'research-agent',
46
- name: 'Research Agent',
47
- description: 'Researches topics',
48
- version: '1.0.0',
49
- type: 'agent',
50
- status: 'dev'
51
- },
52
- contract: {
53
- inputSchema: z.object({
54
- query: z.string()
55
- }),
56
- outputSchema: z.object({
57
- results: z.string()
58
- })
59
- },
60
- modelConfig: {
61
- provider: 'openai',
62
- model: 'gpt-4o',
63
- temperature: 0.7
64
- },
65
- systemPrompt: 'You are a research assistant',
66
- tools: []
67
- }
68
-
69
- let mockRegistry: ResourceRegistry
70
- let mockExecuteResource: ReturnType<typeof vi.fn>
71
- let service: ResourceInvocationService
72
-
73
- beforeEach(() => {
74
- // Create mock registry
75
- mockRegistry = {
76
- getResourceDefinition: vi.fn(),
77
- getRelationships: vi.fn().mockReturnValue(undefined)
78
- } as unknown as ResourceRegistry
79
-
80
- // Create mock execute function
81
- mockExecuteResource = vi.fn()
82
-
83
- // Create service instance
84
- service = new ResourceInvocationService(mockRegistry, mockExecuteResource)
85
- })
86
-
87
- describe('executeSync', () => {
88
- it('validates resource exists', async () => {
89
- // Setup: Mock registry returns undefined for resourceId
90
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(null)
91
-
92
- const result = await service.executeSync(
93
- 'non-existent-resource',
94
- { email: 'test@test.com', name: 'Test' },
95
- 'test-org',
96
- mockContext
97
- )
98
-
99
- expect(result.success).toBe(false)
100
- expect(result.error).toContain('not found')
101
- expect(result.error).toContain('non-existent-resource')
102
- expect(mockRegistry.getResourceDefinition).toHaveBeenCalledWith('test-org', 'non-existent-resource')
103
- })
104
-
105
- it('invokes workflow and returns result', async () => {
106
- // Setup: Mock registry returns workflow definition
107
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockWorkflowDefinition)
108
-
109
- // Mock successful execution
110
- const mockResult: ResourceInvocationResult = {
111
- success: true,
112
- output: { valid: true, errors: [] },
113
- executionId: 'exec-789',
114
- resourceType: 'workflow'
115
- }
116
- mockExecuteResource.mockResolvedValue(mockResult)
117
-
118
- const result = await service.executeSync(
119
- 'validation-workflow',
120
- { email: 'test@test.com', name: 'Test User' },
121
- 'test-org',
122
- mockContext
123
- )
124
-
125
- expect(result.success).toBe(true)
126
- expect(result.resourceType).toBe('workflow')
127
- expect(result.output).toEqual({ valid: true, errors: [] })
128
- expect(result.executionId).toBe('exec-789')
129
-
130
- // Verify executeResource called with correct parameters
131
- expect(mockExecuteResource).toHaveBeenCalledWith(
132
- {
133
- resourceId: 'validation-workflow',
134
- input: { email: 'test@test.com', name: 'Test User' },
135
- organizationId: 'org-123',
136
- organizationName: 'test-org'
137
- },
138
- mockContext
139
- )
140
- })
141
-
142
- it('invokes agent and returns result', async () => {
143
- // Setup: Mock registry returns agent definition
144
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockAgentDefinition)
145
-
146
- // Mock successful execution
147
- const mockResult: ResourceInvocationResult = {
148
- success: true,
149
- output: { results: 'Research findings...' },
150
- executionId: 'exec-999',
151
- resourceType: 'agent'
152
- }
153
- mockExecuteResource.mockResolvedValue(mockResult)
154
-
155
- const result = await service.executeSync(
156
- 'research-agent',
157
- { query: 'AI trends' },
158
- 'test-org',
159
- mockContext
160
- )
161
-
162
- expect(result.success).toBe(true)
163
- expect(result.resourceType).toBe('agent')
164
- expect(result.output).toEqual({ results: 'Research findings...' })
165
- expect(result.executionId).toBe('exec-999')
166
- })
167
-
168
- it('validates input against resource contract', async () => {
169
- // Setup: Mock registry returns workflow with Zod schema
170
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockWorkflowDefinition)
171
-
172
- // Invalid input (missing required fields)
173
- const result = await service.executeSync(
174
- 'validation-workflow',
175
- { email: 'invalid-email' }, // Missing 'name', invalid email
176
- 'test-org',
177
- mockContext
178
- )
179
-
180
- expect(result.success).toBe(false)
181
- expect(result.error).toContain('Input validation failed')
182
- expect(mockExecuteResource).not.toHaveBeenCalled()
183
- })
184
-
185
- it('passes parent context to nested execution', async () => {
186
- // Setup: Mock registry returns workflow
187
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockWorkflowDefinition)
188
-
189
- // Mock executor that captures context
190
- const capturedContext = vi.fn()
191
- mockExecuteResource.mockImplementation(async (request, context) => {
192
- capturedContext(context)
193
- return {
194
- success: true,
195
- output: { valid: true, errors: [] },
196
- executionId: 'exec-nested',
197
- resourceType: 'workflow'
198
- }
199
- })
200
-
201
- await service.executeSync(
202
- 'validation-workflow',
203
- { email: 'test@test.com', name: 'Test' },
204
- 'test-org',
205
- mockContext
206
- )
207
-
208
- // Verify parent context was passed
209
- expect(capturedContext).toHaveBeenCalledWith(mockContext)
210
- })
211
-
212
- it('handles execution errors from executor', async () => {
213
- // Setup: Mock registry returns workflow
214
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockWorkflowDefinition)
215
-
216
- // Mock failed execution
217
- const mockResult: ResourceInvocationResult = {
218
- success: false,
219
- output: null,
220
- executionId: 'exec-fail',
221
- resourceType: 'workflow',
222
- error: 'Execution timeout'
223
- }
224
- mockExecuteResource.mockResolvedValue(mockResult)
225
-
226
- const result = await service.executeSync(
227
- 'validation-workflow',
228
- { email: 'test@test.com', name: 'Test' },
229
- 'test-org',
230
- mockContext
231
- )
232
-
233
- expect(result.success).toBe(false)
234
- expect(result.error).toBe('Execution timeout')
235
- expect(result.resourceType).toBe('workflow')
236
- })
237
-
238
- it('preserves organization context through invocation', async () => {
239
- // Setup: Mock registry returns workflow
240
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockWorkflowDefinition)
241
-
242
- mockExecuteResource.mockResolvedValue({
243
- success: true,
244
- output: { valid: true, errors: [] },
245
- executionId: 'exec-org',
246
- resourceType: 'workflow'
247
- })
248
-
249
- await service.executeSync(
250
- 'validation-workflow',
251
- { email: 'test@test.com', name: 'Test' },
252
- 'test-org',
253
- mockContext
254
- )
255
-
256
- // Verify organizationId and organizationName passed correctly
257
- expect(mockExecuteResource).toHaveBeenCalledWith(
258
- expect.objectContaining({
259
- organizationId: 'org-123',
260
- organizationName: 'test-org'
261
- }),
262
- mockContext
263
- )
264
- })
265
-
266
- it('handles workflow with null outputSchema', async () => {
267
- // Create workflow with no outputSchema (fire-and-forget)
268
- const fireAndForgetWorkflow: WorkflowDefinition = {
269
- ...mockWorkflowDefinition,
270
- contract: {
271
- inputSchema: z.object({ data: z.string() }),
272
- outputSchema: null
273
- }
274
- }
275
-
276
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(fireAndForgetWorkflow)
277
-
278
- mockExecuteResource.mockResolvedValue({
279
- success: true,
280
- output: null,
281
- executionId: 'exec-fire',
282
- resourceType: 'workflow'
283
- })
284
-
285
- const result = await service.executeSync(
286
- 'fire-and-forget-workflow',
287
- { data: 'test' },
288
- 'test-org',
289
- mockContext
290
- )
291
-
292
- expect(result.success).toBe(true)
293
- expect(result.output).toBeNull()
294
- })
295
- })
296
-
297
- describe('createResourceInvocationService', () => {
298
- it('creates service with valid dependencies', () => {
299
- const service = createResourceInvocationService(mockRegistry, mockExecuteResource)
300
-
301
- expect(service).toBeInstanceOf(ResourceInvocationService)
302
- })
303
-
304
- it('throws if registry not provided', () => {
305
- expect(() => {
306
- createResourceInvocationService(null as unknown as ResourceRegistry, mockExecuteResource)
307
- }).toThrow('ResourceRegistry required')
308
- })
309
-
310
- it('throws if executeResource callback not provided', () => {
311
- expect(() => {
312
- createResourceInvocationService(mockRegistry, null as unknown as ExecuteResourceCallback)
313
- }).toThrow('executeResource callback required')
314
- })
315
- })
316
-
317
- describe('multi-tenancy safety', () => {
318
- it('scopes resource lookup by organization name', async () => {
319
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockWorkflowDefinition)
320
-
321
- mockExecuteResource.mockResolvedValue({
322
- success: true,
323
- output: { valid: true, errors: [] },
324
- executionId: 'exec-tenant',
325
- resourceType: 'workflow'
326
- })
327
-
328
- await service.executeSync(
329
- 'validation-workflow',
330
- { email: 'test@test.com', name: 'Test' },
331
- 'acme-corp',
332
- mockContext
333
- )
334
-
335
- // Verify registry called with correct organization name
336
- expect(mockRegistry.getResourceDefinition).toHaveBeenCalledWith('acme-corp', 'validation-workflow')
337
- })
338
-
339
- it('passes organization context to nested execution', async () => {
340
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockWorkflowDefinition)
341
-
342
- const contextWithOrg = createMockExecutionContext({
343
- organizationId: 'org-different',
344
- organizationName: 'different-org'
345
- })
346
-
347
- mockExecuteResource.mockResolvedValue({
348
- success: true,
349
- output: { valid: true, errors: [] },
350
- executionId: 'exec-ctx',
351
- resourceType: 'workflow'
352
- })
353
-
354
- await service.executeSync(
355
- 'validation-workflow',
356
- { email: 'test@test.com', name: 'Test' },
357
- 'different-org',
358
- contextWithOrg
359
- )
360
-
361
- // Verify correct organization context passed
362
- expect(mockExecuteResource).toHaveBeenCalledWith(
363
- expect.objectContaining({
364
- organizationId: 'org-different',
365
- organizationName: 'different-org'
366
- }),
367
- contextWithOrg
368
- )
369
- })
370
- })
371
-
372
- describe('relationship enforcement', () => {
373
- it('allows invocation when relationship is declared (workflow target)', async () => {
374
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockWorkflowDefinition)
375
- vi.mocked(mockRegistry.getRelationships).mockReturnValue({
376
- 'parent-agent': {
377
- triggers: { workflows: ['validation-workflow'] }
378
- }
379
- })
380
-
381
- mockExecuteResource.mockResolvedValue({
382
- success: true,
383
- output: { valid: true, errors: [] },
384
- executionId: 'exec-rel',
385
- resourceType: 'workflow'
386
- })
387
-
388
- const result = await service.executeSync(
389
- 'validation-workflow',
390
- { email: 'test@test.com', name: 'Test' },
391
- 'test-org',
392
- mockContext
393
- )
394
-
395
- expect(result.success).toBe(true)
396
- })
397
-
398
- it('allows invocation when relationship is declared (agent target)', async () => {
399
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockAgentDefinition)
400
- vi.mocked(mockRegistry.getRelationships).mockReturnValue({
401
- 'parent-agent': {
402
- triggers: { agents: ['research-agent'] }
403
- }
404
- })
405
-
406
- mockExecuteResource.mockResolvedValue({
407
- success: true,
408
- output: { results: 'findings' },
409
- executionId: 'exec-agent-rel',
410
- resourceType: 'agent'
411
- })
412
-
413
- const result = await service.executeSync(
414
- 'research-agent',
415
- { query: 'test' },
416
- 'test-org',
417
- mockContext
418
- )
419
-
420
- expect(result.success).toBe(true)
421
- })
422
-
423
- it('throws when invocation is not declared', async () => {
424
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockWorkflowDefinition)
425
- vi.mocked(mockRegistry.getRelationships).mockReturnValue({
426
- 'parent-agent': {
427
- triggers: { workflows: ['other-workflow'] }
428
- }
429
- })
430
-
431
- await expect(
432
- service.executeSync(
433
- 'validation-workflow',
434
- { email: 'test@test.com', name: 'Test' },
435
- 'test-org',
436
- mockContext
437
- )
438
- ).rejects.toThrow('Undeclared resource invocation')
439
- })
440
-
441
- it('throws when caller has no entry in relationships', async () => {
442
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockWorkflowDefinition)
443
- vi.mocked(mockRegistry.getRelationships).mockReturnValue({
444
- 'some-other-resource': {
445
- triggers: { workflows: ['validation-workflow'] }
446
- }
447
- })
448
-
449
- await expect(
450
- service.executeSync(
451
- 'validation-workflow',
452
- { email: 'test@test.com', name: 'Test' },
453
- 'test-org',
454
- mockContext
455
- )
456
- ).rejects.toThrow('Undeclared resource invocation')
457
- })
458
-
459
- it('skips enforcement when org has no relationships (undefined)', async () => {
460
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockWorkflowDefinition)
461
- vi.mocked(mockRegistry.getRelationships).mockReturnValue(undefined)
462
-
463
- mockExecuteResource.mockResolvedValue({
464
- success: true,
465
- output: { valid: true, errors: [] },
466
- executionId: 'exec-no-rel',
467
- resourceType: 'workflow'
468
- })
469
-
470
- const result = await service.executeSync(
471
- 'validation-workflow',
472
- { email: 'test@test.com', name: 'Test' },
473
- 'test-org',
474
- mockContext
475
- )
476
-
477
- expect(result.success).toBe(true)
478
- })
479
-
480
- it('error message includes actionable fix instructions', async () => {
481
- vi.mocked(mockRegistry.getResourceDefinition).mockReturnValue(mockWorkflowDefinition)
482
- vi.mocked(mockRegistry.getRelationships).mockReturnValue({
483
- 'parent-agent': {
484
- triggers: { workflows: ['other-workflow'] }
485
- }
486
- })
487
-
488
- await expect(
489
- service.executeSync(
490
- 'validation-workflow',
491
- { email: 'test@test.com', name: 'Test' },
492
- 'test-org',
493
- mockContext
494
- )
495
- ).rejects.toThrow(
496
- `Add to relationships: { 'parent-agent': { triggers: { workflows: ['validation-workflow'] } } }`
497
- )
498
- })
499
- })
500
- })