@lssm/example.agent-console 0.0.0-canary-20251215234153 → 0.0.0-canary-20251216023757

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 (100) hide show
  1. package/.turbo/turbo-build.log +38 -28
  2. package/CHANGELOG.md +6 -6
  3. package/dist/agent/agent.contracts.js +1 -0
  4. package/dist/{entities/agent.js → agent/agent.entity.js} +1 -1
  5. package/dist/agent/agent.enum.js +1 -0
  6. package/dist/agent/agent.event.js +1 -0
  7. package/dist/agent/agent.handler.js +1 -0
  8. package/dist/agent/agent.presentation.js +1 -0
  9. package/dist/agent/agent.schema.js +1 -0
  10. package/dist/agent/index.js +1 -0
  11. package/dist/handlers/index.js +1 -1
  12. package/dist/index.js +1 -1
  13. package/dist/presentations/index.js +1 -1
  14. package/dist/run/index.js +1 -0
  15. package/dist/run/run.contracts.js +1 -0
  16. package/dist/run/run.entity.js +1 -0
  17. package/dist/run/run.enum.js +1 -0
  18. package/dist/run/run.event.js +1 -0
  19. package/dist/run/run.handler.js +1 -0
  20. package/dist/run/run.presentation.js +1 -0
  21. package/dist/run/run.schema.js +1 -0
  22. package/dist/shared/index.js +1 -0
  23. package/dist/shared/mock-agents.js +1 -0
  24. package/dist/shared/mock-runs.js +1 -0
  25. package/dist/shared/mock-tools.js +1 -0
  26. package/dist/tool/index.js +1 -0
  27. package/dist/tool/tool.contracts.js +1 -0
  28. package/dist/tool/tool.entity.js +1 -0
  29. package/dist/tool/tool.enum.js +1 -0
  30. package/dist/tool/tool.event.js +1 -0
  31. package/dist/tool/tool.handler.js +1 -0
  32. package/dist/tool/tool.presentation.js +1 -0
  33. package/dist/tool/tool.schema.js +1 -0
  34. package/package.json +59 -39
  35. package/src/agent/agent.contracts.ts +275 -0
  36. package/src/agent/agent.entity.ts +84 -0
  37. package/src/agent/agent.enum.ts +31 -0
  38. package/src/agent/agent.event.ts +109 -0
  39. package/src/{handlers/agent.handlers.ts → agent/agent.handler.ts} +23 -78
  40. package/src/{presentations/agent-list.ts → agent/agent.presentation.ts} +26 -14
  41. package/src/agent/agent.schema.ts +147 -0
  42. package/src/agent/index.ts +65 -0
  43. package/src/handlers/index.ts +17 -44
  44. package/src/index.ts +6 -15
  45. package/src/presentations/index.ts +13 -34
  46. package/src/run/index.ts +65 -0
  47. package/src/run/run.contracts.ts +266 -0
  48. package/src/run/run.entity.ts +126 -0
  49. package/src/run/run.enum.ts +45 -0
  50. package/src/run/run.event.ts +211 -0
  51. package/src/run/run.handler.ts +103 -0
  52. package/src/run/run.presentation.ts +47 -0
  53. package/src/run/run.schema.ts +139 -0
  54. package/src/shared/index.ts +6 -0
  55. package/src/shared/mock-agents.ts +83 -0
  56. package/src/shared/mock-runs.ts +108 -0
  57. package/src/shared/mock-tools.ts +146 -0
  58. package/src/tool/index.ts +35 -0
  59. package/src/tool/tool.contracts.ts +180 -0
  60. package/src/tool/tool.entity.ts +66 -0
  61. package/src/tool/tool.enum.ts +34 -0
  62. package/src/tool/tool.event.ts +84 -0
  63. package/src/tool/tool.handler.ts +107 -0
  64. package/src/{presentations/tool-registry.ts → tool/tool.presentation.ts} +12 -17
  65. package/src/tool/tool.schema.ts +134 -0
  66. package/tsconfig.tsbuildinfo +1 -1
  67. package/dist/contracts/agent.js +0 -1
  68. package/dist/contracts/index.js +0 -1
  69. package/dist/contracts/run.js +0 -1
  70. package/dist/contracts/tool.js +0 -1
  71. package/dist/entities/index.js +0 -1
  72. package/dist/entities/log.js +0 -1
  73. package/dist/entities/run.js +0 -1
  74. package/dist/entities/tool.js +0 -1
  75. package/dist/events.js +0 -1
  76. package/dist/handlers/agent.handlers.js +0 -1
  77. package/dist/handlers/mock-data.js +0 -1
  78. package/dist/handlers/run.handlers.js +0 -1
  79. package/dist/handlers/tool.handlers.js +0 -1
  80. package/dist/presentations/agent-list.js +0 -1
  81. package/dist/presentations/dashboard.js +0 -1
  82. package/dist/presentations/run-list.js +0 -1
  83. package/dist/presentations/tool-registry.js +0 -1
  84. package/src/contracts/agent.ts +0 -501
  85. package/src/contracts/index.ts +0 -29
  86. package/src/contracts/run.ts +0 -561
  87. package/src/contracts/tool.ts +0 -392
  88. package/src/entities/agent.ts +0 -151
  89. package/src/entities/index.ts +0 -20
  90. package/src/entities/log.ts +0 -76
  91. package/src/entities/run.ts +0 -240
  92. package/src/entities/tool.ts +0 -105
  93. package/src/events.ts +0 -419
  94. package/src/handlers/mock-data.ts +0 -413
  95. package/src/handlers/run.handlers.ts +0 -331
  96. package/src/handlers/tool.handlers.ts +0 -188
  97. package/src/presentations/dashboard.ts +0 -29
  98. package/src/presentations/run-list.ts +0 -76
  99. /package/dist/{feature.js → agent.feature.js} +0 -0
  100. /package/src/{feature.ts → agent.feature.ts} +0 -0
@@ -0,0 +1,180 @@
1
+ import { defineCommand, defineQuery } from '@lssm/lib.contracts/spec';
2
+ import { defineSchemaModel, ScalarTypeEnum } from '@lssm/lib.schema';
3
+ import { ToolCategoryEnum, ToolStatusEnum } from './tool.enum';
4
+ import { ToolModel, ToolSummaryModel, CreateToolInputModel, UpdateToolInputModel } from './tool.schema';
5
+
6
+ const OWNERS = ['agent-console-team'] as const;
7
+
8
+ /**
9
+ * CreateToolCommand - Creates a new tool definition.
10
+ */
11
+ export const CreateToolCommand = defineCommand({
12
+ meta: {
13
+ name: 'agent.tool.create',
14
+ version: 1,
15
+ stability: 'stable',
16
+ owners: [...OWNERS],
17
+ tags: ['tool', 'create'],
18
+ description: 'Creates a new AI tool definition.',
19
+ goal: 'Allow users to define new tools that agents can use.',
20
+ context: 'Called from the tool builder UI when creating a new tool.',
21
+ },
22
+ io: {
23
+ input: CreateToolInputModel,
24
+ output: defineSchemaModel({
25
+ name: 'CreateToolOutput',
26
+ fields: {
27
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
28
+ name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
29
+ slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
30
+ status: { type: ToolStatusEnum, isOptional: false },
31
+ },
32
+ }),
33
+ errors: {
34
+ SLUG_EXISTS: { description: 'A tool with this slug already exists in the organization', http: 409, gqlCode: 'SLUG_EXISTS', when: 'Slug is already taken' },
35
+ },
36
+ },
37
+ policy: { auth: 'user' },
38
+ sideEffects: {
39
+ emits: [{ name: 'tool.created', version: 1, when: 'Tool is successfully created', payload: ToolSummaryModel }],
40
+ audit: ['tool.created'],
41
+ },
42
+ });
43
+
44
+ /**
45
+ * UpdateToolCommand - Updates an existing tool.
46
+ */
47
+ export const UpdateToolCommand = defineCommand({
48
+ meta: {
49
+ name: 'agent.tool.update',
50
+ version: 1,
51
+ stability: 'stable',
52
+ owners: [...OWNERS],
53
+ tags: ['tool', 'update'],
54
+ description: 'Updates an existing AI tool definition.',
55
+ goal: 'Allow users to modify tool settings and configuration.',
56
+ context: 'Called from the tool settings UI.',
57
+ },
58
+ io: {
59
+ input: UpdateToolInputModel,
60
+ output: defineSchemaModel({
61
+ name: 'UpdateToolOutput',
62
+ fields: {
63
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
64
+ name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
65
+ status: { type: ToolStatusEnum, isOptional: false },
66
+ updatedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
67
+ },
68
+ }),
69
+ errors: {
70
+ TOOL_NOT_FOUND: { description: 'The specified tool does not exist', http: 404, gqlCode: 'TOOL_NOT_FOUND', when: 'Tool ID is invalid' },
71
+ },
72
+ },
73
+ policy: { auth: 'user' },
74
+ sideEffects: {
75
+ emits: [{ name: 'tool.updated', version: 1, when: 'Tool is updated', payload: ToolSummaryModel }],
76
+ audit: ['tool.updated'],
77
+ },
78
+ });
79
+
80
+ /**
81
+ * GetToolQuery - Retrieves a tool by ID.
82
+ */
83
+ export const GetToolQuery = defineQuery({
84
+ meta: {
85
+ name: 'agent.tool.get',
86
+ version: 1,
87
+ stability: 'stable',
88
+ owners: [...OWNERS],
89
+ tags: ['tool', 'get'],
90
+ description: 'Retrieves a tool by its ID.',
91
+ goal: 'View detailed tool configuration.',
92
+ context: 'Called when viewing tool details or editing.',
93
+ },
94
+ io: {
95
+ input: defineSchemaModel({ name: 'GetToolInput', fields: { toolId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false } } }),
96
+ output: ToolModel,
97
+ errors: { TOOL_NOT_FOUND: { description: 'The specified tool does not exist', http: 404, gqlCode: 'TOOL_NOT_FOUND', when: 'Tool ID is invalid' } },
98
+ },
99
+ policy: { auth: 'user' },
100
+ });
101
+
102
+ /**
103
+ * ListToolsQuery - Lists tools for an organization.
104
+ */
105
+ export const ListToolsQuery = defineQuery({
106
+ meta: {
107
+ name: 'agent.tool.list',
108
+ version: 1,
109
+ stability: 'stable',
110
+ owners: [...OWNERS],
111
+ tags: ['tool', 'list'],
112
+ description: 'Lists tools for an organization with optional filtering.',
113
+ goal: 'Browse and search available tools.',
114
+ context: 'Tool list/dashboard view.',
115
+ },
116
+ io: {
117
+ input: defineSchemaModel({
118
+ name: 'ListToolsInput',
119
+ fields: {
120
+ organizationId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
121
+ category: { type: ToolCategoryEnum, isOptional: true },
122
+ status: { type: ToolStatusEnum, isOptional: true },
123
+ search: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
124
+ limit: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true, defaultValue: 20 },
125
+ offset: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true, defaultValue: 0 },
126
+ },
127
+ }),
128
+ output: defineSchemaModel({
129
+ name: 'ListToolsOutput',
130
+ fields: {
131
+ items: { type: ToolSummaryModel, isArray: true, isOptional: false },
132
+ total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
133
+ hasMore: { type: ScalarTypeEnum.Boolean(), isOptional: false },
134
+ },
135
+ }),
136
+ },
137
+ policy: { auth: 'user' },
138
+ });
139
+
140
+ /**
141
+ * TestToolCommand - Tests a tool with sample input.
142
+ */
143
+ export const TestToolCommand = defineCommand({
144
+ meta: {
145
+ name: 'agent.tool.test',
146
+ version: 1,
147
+ stability: 'stable',
148
+ owners: [...OWNERS],
149
+ tags: ['tool', 'test'],
150
+ description: 'Tests a tool with sample input to verify it works correctly.',
151
+ goal: 'Validate tool configuration before deployment.',
152
+ context: 'Tool builder UI - test panel.',
153
+ },
154
+ io: {
155
+ input: defineSchemaModel({
156
+ name: 'TestToolInput',
157
+ fields: {
158
+ toolId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
159
+ testInput: { type: ScalarTypeEnum.JSONObject(), isOptional: false },
160
+ },
161
+ }),
162
+ output: defineSchemaModel({
163
+ name: 'TestToolOutput',
164
+ fields: {
165
+ success: { type: ScalarTypeEnum.Boolean(), isOptional: false },
166
+ output: { type: ScalarTypeEnum.JSONObject(), isOptional: true },
167
+ error: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
168
+ durationMs: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
169
+ },
170
+ }),
171
+ errors: {
172
+ TOOL_NOT_FOUND: { description: 'The specified tool does not exist', http: 404, gqlCode: 'TOOL_NOT_FOUND', when: 'Tool ID is invalid' },
173
+ TOOL_EXECUTION_ERROR: { description: 'Tool execution failed', http: 500, gqlCode: 'TOOL_EXECUTION_ERROR', when: 'Tool returns an error' },
174
+ },
175
+ },
176
+ policy: { auth: 'user' },
177
+ sideEffects: { audit: ['tool.tested'] },
178
+ });
179
+
180
+
@@ -0,0 +1,66 @@
1
+ import { defineEntity, defineEntityEnum, field, index } from '@lssm/lib.schema/entity';
2
+
3
+ /**
4
+ * Tool category enum for entities.
5
+ */
6
+ export const ToolCategoryEntityEnum = defineEntityEnum({
7
+ name: 'ToolCategory',
8
+ values: ['RETRIEVAL', 'COMPUTATION', 'COMMUNICATION', 'INTEGRATION', 'UTILITY', 'CUSTOM'],
9
+ description: 'Category of tool',
10
+ });
11
+
12
+ /**
13
+ * Tool status enum for entities.
14
+ */
15
+ export const ToolStatusEntityEnum = defineEntityEnum({
16
+ name: 'ToolStatus',
17
+ values: ['DRAFT', 'ACTIVE', 'DEPRECATED', 'DISABLED'],
18
+ description: 'Status of tool',
19
+ });
20
+
21
+ /**
22
+ * Implementation type enum for entities.
23
+ */
24
+ export const ImplementationTypeEntityEnum = defineEntityEnum({
25
+ name: 'ImplementationType',
26
+ values: ['http', 'function', 'workflow'],
27
+ description: 'How the tool is implemented',
28
+ });
29
+
30
+ /**
31
+ * Tool entity - Represents an AI tool definition.
32
+ */
33
+ export const ToolEntity = defineEntity({
34
+ name: 'Tool',
35
+ schema: 'agent_console',
36
+ description: 'An AI tool that can be used by agents.',
37
+ fields: {
38
+ id: field.id(),
39
+ organizationId: field.string({ description: 'Organization that owns this tool' }),
40
+ name: field.string({ description: 'Tool name' }),
41
+ slug: field.string({ description: 'URL-safe identifier' }),
42
+ description: field.string({ description: 'Tool description' }),
43
+ category: field.enum('ToolCategory', { default: 'CUSTOM' }),
44
+ status: field.enum('ToolStatus', { default: 'DRAFT' }),
45
+ parametersSchema: field.json({ description: 'JSON Schema for tool parameters' }),
46
+ outputSchema: field.json({ isOptional: true, description: 'JSON Schema for tool output' }),
47
+ implementationType: field.enum('ImplementationType'),
48
+ implementationConfig: field.json({ description: 'Implementation configuration' }),
49
+ maxInvocationsPerMinute: field.int({ isOptional: true, description: 'Rate limit' }),
50
+ timeoutMs: field.int({ default: 30000, description: 'Execution timeout' }),
51
+ version: field.string({ default: '1.0.0', description: 'Tool version' }),
52
+ tags: field.string({ isArray: true, isOptional: true, description: 'Tags for categorization' }),
53
+ createdAt: field.createdAt(),
54
+ updatedAt: field.updatedAt(),
55
+ createdById: field.string({ isOptional: true, description: 'User who created this tool' }),
56
+ agents: field.hasMany('Agent', { description: 'Agents using this tool' }),
57
+ },
58
+ indexes: [
59
+ index.unique(['organizationId', 'slug']),
60
+ index.on(['organizationId', 'category']),
61
+ index.on(['organizationId', 'status']),
62
+ ],
63
+ enums: [ToolCategoryEntityEnum, ToolStatusEntityEnum, ImplementationTypeEntityEnum],
64
+ });
65
+
66
+
@@ -0,0 +1,34 @@
1
+ import { defineEnum } from '@lssm/lib.schema';
2
+
3
+ /**
4
+ * Tool category enum.
5
+ */
6
+ export const ToolCategoryEnum = defineEnum('ToolCategory', [
7
+ 'RETRIEVAL',
8
+ 'COMPUTATION',
9
+ 'COMMUNICATION',
10
+ 'INTEGRATION',
11
+ 'UTILITY',
12
+ 'CUSTOM',
13
+ ]);
14
+
15
+ /**
16
+ * Tool status enum.
17
+ */
18
+ export const ToolStatusEnum = defineEnum('ToolStatus', [
19
+ 'DRAFT',
20
+ 'ACTIVE',
21
+ 'DEPRECATED',
22
+ 'DISABLED',
23
+ ]);
24
+
25
+ /**
26
+ * Implementation type enum.
27
+ */
28
+ export const ImplementationTypeEnum = defineEnum('ImplementationType', [
29
+ 'http',
30
+ 'function',
31
+ 'workflow',
32
+ ]);
33
+
34
+
@@ -0,0 +1,84 @@
1
+ import { defineEvent, defineSchemaModel } from '@lssm/lib.contracts';
2
+ import { ScalarTypeEnum } from '@lssm/lib.schema';
3
+
4
+ /**
5
+ * Payload for tool created event.
6
+ */
7
+ const ToolCreatedPayload = defineSchemaModel({
8
+ name: 'ToolCreatedPayload',
9
+ description: 'Payload for tool created event',
10
+ fields: {
11
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
12
+ organizationId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
13
+ name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
14
+ slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
15
+ category: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
16
+ implementationType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
17
+ createdById: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
18
+ createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
19
+ },
20
+ });
21
+
22
+ /**
23
+ * ToolCreatedEvent - A new tool was created.
24
+ */
25
+ export const ToolCreatedEvent = defineEvent({
26
+ name: 'agent.tool.created',
27
+ version: 1,
28
+ description: 'A new AI tool was created.',
29
+ payload: ToolCreatedPayload,
30
+ });
31
+
32
+ /**
33
+ * Payload for tool updated event.
34
+ */
35
+ const ToolUpdatedPayload = defineSchemaModel({
36
+ name: 'ToolUpdatedPayload',
37
+ description: 'Payload for tool updated event',
38
+ fields: {
39
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
40
+ organizationId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
41
+ name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
42
+ status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
43
+ updatedFields: { type: ScalarTypeEnum.String_unsecure(), isArray: true, isOptional: false },
44
+ updatedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
45
+ },
46
+ });
47
+
48
+ /**
49
+ * ToolUpdatedEvent - A tool was updated.
50
+ */
51
+ export const ToolUpdatedEvent = defineEvent({
52
+ name: 'agent.tool.updated',
53
+ version: 1,
54
+ description: 'An AI tool configuration was updated.',
55
+ payload: ToolUpdatedPayload,
56
+ });
57
+
58
+ /**
59
+ * Payload for tool status changed event.
60
+ */
61
+ const ToolStatusChangedPayload = defineSchemaModel({
62
+ name: 'ToolStatusChangedPayload',
63
+ description: 'Payload for tool status changed event',
64
+ fields: {
65
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
66
+ organizationId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
67
+ name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
68
+ previousStatus: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
69
+ newStatus: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
70
+ changedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
71
+ },
72
+ });
73
+
74
+ /**
75
+ * ToolStatusChangedEvent - A tool's status was changed.
76
+ */
77
+ export const ToolStatusChangedEvent = defineEvent({
78
+ name: 'agent.tool.statusChanged',
79
+ version: 1,
80
+ description: 'An AI tool status was changed (activated, deprecated, disabled).',
81
+ payload: ToolStatusChangedPayload,
82
+ });
83
+
84
+
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Mock handlers for Tool contracts.
3
+ */
4
+ import { MOCK_TOOLS } from '../shared/mock-tools';
5
+
6
+ export interface ListToolsInput {
7
+ organizationId: string;
8
+ category?: 'RETRIEVAL' | 'COMPUTATION' | 'COMMUNICATION' | 'INTEGRATION' | 'UTILITY' | 'CUSTOM';
9
+ status?: 'DRAFT' | 'ACTIVE' | 'DEPRECATED' | 'DISABLED';
10
+ search?: string;
11
+ limit?: number;
12
+ offset?: number;
13
+ }
14
+
15
+ export interface ToolSummary {
16
+ id: string;
17
+ name: string;
18
+ slug: string;
19
+ description: string;
20
+ category: 'RETRIEVAL' | 'COMPUTATION' | 'COMMUNICATION' | 'INTEGRATION' | 'UTILITY' | 'CUSTOM';
21
+ status: 'DRAFT' | 'ACTIVE' | 'DEPRECATED' | 'DISABLED';
22
+ version: string;
23
+ createdAt: Date;
24
+ }
25
+
26
+ export interface ListToolsOutput {
27
+ items: ToolSummary[];
28
+ total: number;
29
+ hasMore: boolean;
30
+ }
31
+
32
+ /**
33
+ * Mock handler for ListToolsQuery.
34
+ */
35
+ export async function mockListToolsHandler(input: ListToolsInput): Promise<ListToolsOutput> {
36
+ const { organizationId, category, status, search, limit = 20, offset = 0 } = input;
37
+
38
+ let filtered = MOCK_TOOLS.filter((t) => t.organizationId === organizationId);
39
+ if (category) filtered = filtered.filter((t) => t.category === category);
40
+ if (status) filtered = filtered.filter((t) => t.status === status);
41
+ if (search) {
42
+ const q = search.toLowerCase();
43
+ filtered = filtered.filter((t) => t.name.toLowerCase().includes(q) || t.description.toLowerCase().includes(q));
44
+ }
45
+
46
+ const total = filtered.length;
47
+ const items = filtered.slice(offset, offset + limit).map((t) => ({
48
+ id: t.id,
49
+ name: t.name,
50
+ slug: t.slug,
51
+ description: t.description,
52
+ category: t.category,
53
+ status: t.status,
54
+ version: t.version,
55
+ createdAt: t.createdAt,
56
+ }));
57
+
58
+ return { items, total, hasMore: offset + limit < total };
59
+ }
60
+
61
+ /**
62
+ * Mock handler for GetToolQuery.
63
+ */
64
+ export async function mockGetToolHandler(input: { toolId: string }) {
65
+ const tool = MOCK_TOOLS.find((t) => t.id === input.toolId);
66
+ if (!tool) throw new Error('TOOL_NOT_FOUND');
67
+ return tool;
68
+ }
69
+
70
+ /**
71
+ * Mock handler for CreateToolCommand.
72
+ */
73
+ export async function mockCreateToolHandler(input: {
74
+ organizationId: string;
75
+ name: string;
76
+ slug: string;
77
+ description: string;
78
+ implementationType: 'http' | 'function' | 'workflow';
79
+ }) {
80
+ const exists = MOCK_TOOLS.some((t) => t.organizationId === input.organizationId && t.slug === input.slug);
81
+ if (exists) throw new Error('SLUG_EXISTS');
82
+ return { id: `tool-${Date.now()}`, name: input.name, slug: input.slug, status: 'DRAFT' as const };
83
+ }
84
+
85
+ /**
86
+ * Mock handler for UpdateToolCommand.
87
+ */
88
+ export async function mockUpdateToolHandler(input: { toolId: string; name?: string; status?: 'DRAFT' | 'ACTIVE' | 'DEPRECATED' | 'DISABLED' }) {
89
+ const tool = MOCK_TOOLS.find((t) => t.id === input.toolId);
90
+ if (!tool) throw new Error('TOOL_NOT_FOUND');
91
+ return { id: tool.id, name: input.name ?? tool.name, status: input.status ?? tool.status, updatedAt: new Date() };
92
+ }
93
+
94
+ /**
95
+ * Mock handler for TestToolCommand.
96
+ */
97
+ export async function mockTestToolHandler(input: { toolId: string; testInput: Record<string, unknown> }) {
98
+ const tool = MOCK_TOOLS.find((t) => t.id === input.toolId);
99
+ if (!tool) throw new Error('TOOL_NOT_FOUND');
100
+
101
+ // Simulate tool execution
102
+ const startTime = Date.now();
103
+ await new Promise((resolve) => setTimeout(resolve, 100));
104
+
105
+ return { success: true, output: { result: 'Test successful', input: input.testInput }, durationMs: Date.now() - startTime };
106
+ }
107
+
@@ -1,31 +1,26 @@
1
- /**
2
- * Tool Registry Presentation Descriptor
3
- */
4
1
  import type { PresentationDescriptorV2 } from '@lssm/lib.contracts';
5
- import { ToolSummaryModel } from '../contracts/tool';
2
+ import { ToolSummaryModel } from './tool.schema';
6
3
 
7
4
  /**
8
- * Presentation for displaying the tool registry.
5
+ * Presentation for displaying a list of tools.
9
6
  */
10
- export const ToolRegistryPresentation: PresentationDescriptorV2 = {
7
+ export const ToolListPresentation: PresentationDescriptorV2 = {
11
8
  meta: {
12
- name: 'agent-console.tool.registry',
9
+ name: 'agent-console.tool.list',
13
10
  version: 1,
14
- description: 'Registry of available tools organized by category',
11
+ description: 'List view of AI tools with category, status, and version info',
15
12
  domain: 'agent-console',
16
13
  owners: ['agent-console-team'],
17
- tags: ['tool', 'registry', 'list'],
14
+ tags: ['tool', 'list', 'dashboard'],
18
15
  },
19
16
  source: {
20
17
  type: 'component',
21
18
  framework: 'react',
22
- componentKey: 'ToolRegistryView',
19
+ componentKey: 'ToolListView',
23
20
  props: ToolSummaryModel,
24
21
  },
25
22
  targets: ['react', 'markdown', 'application/json'],
26
- policy: {
27
- flags: ['agent-console.enabled'],
28
- },
23
+ policy: { flags: ['agent-console.enabled'] },
29
24
  };
30
25
 
31
26
  /**
@@ -35,7 +30,7 @@ export const ToolDetailPresentation: PresentationDescriptorV2 = {
35
30
  meta: {
36
31
  name: 'agent-console.tool.detail',
37
32
  version: 1,
38
- description: 'Detailed view of a tool with schema and configuration',
33
+ description: 'Detailed view of an AI tool with configuration and test panel',
39
34
  domain: 'agent-console',
40
35
  owners: ['agent-console-team'],
41
36
  tags: ['tool', 'detail'],
@@ -46,7 +41,7 @@ export const ToolDetailPresentation: PresentationDescriptorV2 = {
46
41
  componentKey: 'ToolDetailView',
47
42
  },
48
43
  targets: ['react', 'markdown'],
49
- policy: {
50
- flags: ['agent-console.enabled'],
51
- },
44
+ policy: { flags: ['agent-console.enabled'] },
52
45
  };
46
+
47
+
@@ -0,0 +1,134 @@
1
+ import { defineSchemaModel, ScalarTypeEnum } from '@lssm/lib.schema';
2
+ import {
3
+ ToolCategoryEnum,
4
+ ToolStatusEnum,
5
+ ImplementationTypeEnum,
6
+ } from './tool.enum';
7
+
8
+ /**
9
+ * AI tool definition.
10
+ */
11
+ export const ToolModel = defineSchemaModel({
12
+ name: 'Tool',
13
+ description: 'AI tool definition',
14
+ fields: {
15
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
16
+ organizationId: {
17
+ type: ScalarTypeEnum.String_unsecure(),
18
+ isOptional: false,
19
+ },
20
+ name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
21
+ slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
22
+ description: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
23
+ category: { type: ToolCategoryEnum, isOptional: false },
24
+ status: { type: ToolStatusEnum, isOptional: false },
25
+ parametersSchema: { type: ScalarTypeEnum.JSONObject(), isOptional: false },
26
+ outputSchema: { type: ScalarTypeEnum.JSONObject(), isOptional: true },
27
+ implementationType: { type: ImplementationTypeEnum, isOptional: false },
28
+ implementationConfig: {
29
+ type: ScalarTypeEnum.JSONObject(),
30
+ isOptional: false,
31
+ },
32
+ maxInvocationsPerMinute: {
33
+ type: ScalarTypeEnum.Int_unsecure(),
34
+ isOptional: true,
35
+ },
36
+ timeoutMs: {
37
+ type: ScalarTypeEnum.Int_unsecure(),
38
+ isOptional: false,
39
+ defaultValue: 30000,
40
+ },
41
+ version: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
42
+ tags: {
43
+ type: ScalarTypeEnum.String_unsecure(),
44
+ isArray: true,
45
+ isOptional: true,
46
+ },
47
+ createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
48
+ updatedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
49
+ },
50
+ });
51
+
52
+ /**
53
+ * Summary of a tool for list views.
54
+ */
55
+ export const ToolSummaryModel = defineSchemaModel({
56
+ name: 'ToolSummary',
57
+ description: 'Summary of a tool for list views',
58
+ fields: {
59
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
60
+ name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
61
+ slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
62
+ description: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
63
+ category: { type: ToolCategoryEnum, isOptional: false },
64
+ status: { type: ToolStatusEnum, isOptional: false },
65
+ version: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
66
+ createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
67
+ },
68
+ });
69
+
70
+ /**
71
+ * Input for creating a tool.
72
+ */
73
+ export const CreateToolInputModel = defineSchemaModel({
74
+ name: 'CreateToolInput',
75
+ description: 'Input for creating a tool',
76
+ fields: {
77
+ organizationId: {
78
+ type: ScalarTypeEnum.String_unsecure(),
79
+ isOptional: false,
80
+ },
81
+ name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
82
+ slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
83
+ description: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
84
+ category: { type: ToolCategoryEnum, isOptional: true },
85
+ parametersSchema: { type: ScalarTypeEnum.JSONObject(), isOptional: false },
86
+ outputSchema: { type: ScalarTypeEnum.JSONObject(), isOptional: true },
87
+ implementationType: { type: ImplementationTypeEnum, isOptional: false },
88
+ implementationConfig: {
89
+ type: ScalarTypeEnum.JSONObject(),
90
+ isOptional: false,
91
+ },
92
+ maxInvocationsPerMinute: {
93
+ type: ScalarTypeEnum.Int_unsecure(),
94
+ isOptional: true,
95
+ },
96
+ timeoutMs: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },
97
+ tags: {
98
+ type: ScalarTypeEnum.String_unsecure(),
99
+ isArray: true,
100
+ isOptional: true,
101
+ },
102
+ },
103
+ });
104
+
105
+ /**
106
+ * Input for updating a tool.
107
+ */
108
+ export const UpdateToolInputModel = defineSchemaModel({
109
+ name: 'UpdateToolInput',
110
+ description: 'Input for updating a tool',
111
+ fields: {
112
+ toolId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
113
+ name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: true },
114
+ description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
115
+ status: { type: ToolStatusEnum, isOptional: true },
116
+ parametersSchema: { type: ScalarTypeEnum.JSONObject(), isOptional: true },
117
+ outputSchema: { type: ScalarTypeEnum.JSONObject(), isOptional: true },
118
+ implementationConfig: {
119
+ type: ScalarTypeEnum.JSONObject(),
120
+ isOptional: true,
121
+ },
122
+ maxInvocationsPerMinute: {
123
+ type: ScalarTypeEnum.Int_unsecure(),
124
+ isOptional: true,
125
+ },
126
+ timeoutMs: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },
127
+ tags: {
128
+ type: ScalarTypeEnum.String_unsecure(),
129
+ isArray: true,
130
+ isOptional: true,
131
+ },
132
+ },
133
+ });
134
+