@lssm/example.agent-console 0.0.0-canary-20251225044228 → 0.0.0-canary-20251225052113
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/.turbo/turbo-build$colon$bundle.log +11 -11
- package/.turbo/turbo-build.log +17 -17
- package/CHANGELOG.md +6 -6
- package/dist/agent/agent.operation.d.ts +115 -115
- package/dist/agent/agent.operation.d.ts.map +1 -1
- package/dist/agent/agent.operation.js +152 -4
- package/dist/agent/agent.operation.js.map +1 -1
- package/dist/agent/agent.schema.d.ts +95 -95
- package/dist/run/run.entity.d.ts +56 -56
- package/dist/run/run.enum.d.ts +5 -5
- package/dist/run/run.event.d.ts +70 -70
- package/dist/run/run.operation.d.ts +174 -174
- package/dist/run/run.operation.d.ts.map +1 -1
- package/dist/run/run.operation.js +157 -5
- package/dist/run/run.operation.js.map +1 -1
- package/dist/run/run.schema.d.ts +99 -99
- package/dist/tool/tool.entity.d.ts +24 -24
- package/dist/tool/tool.enum.d.ts +4 -4
- package/dist/tool/tool.event.d.ts +24 -24
- package/dist/tool/tool.handler.d.ts.map +1 -1
- package/dist/tool/tool.operation.d.ts +100 -100
- package/dist/tool/tool.operation.d.ts.map +1 -1
- package/dist/tool/tool.operation.js +116 -3
- package/dist/tool/tool.operation.js.map +1 -1
- package/dist/tool/tool.presentation.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/agent/agent.operation.ts +132 -0
- package/src/run/run.operation.ts +131 -0
- package/src/tool/tool.operation.ts +97 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -61,6 +61,34 @@ const CreateToolCommand = defineCommand({
|
|
|
61
61
|
payload: ToolSummaryModel
|
|
62
62
|
}],
|
|
63
63
|
audit: ["tool.created"]
|
|
64
|
+
},
|
|
65
|
+
acceptance: {
|
|
66
|
+
scenarios: [{
|
|
67
|
+
key: "create-tool-happy-path",
|
|
68
|
+
given: ["User is authenticated", "Organization exists"],
|
|
69
|
+
when: ["User submits valid tool configuration"],
|
|
70
|
+
then: ["New tool is created", "ToolCreated event is emitted"]
|
|
71
|
+
}, {
|
|
72
|
+
key: "create-tool-slug-conflict",
|
|
73
|
+
given: ["Tool with same slug exists"],
|
|
74
|
+
when: ["User submits tool with duplicate slug"],
|
|
75
|
+
then: ["SLUG_EXISTS error is returned"]
|
|
76
|
+
}],
|
|
77
|
+
examples: [{
|
|
78
|
+
key: "create-api-tool",
|
|
79
|
+
input: {
|
|
80
|
+
name: "Weather API",
|
|
81
|
+
slug: "weather-api",
|
|
82
|
+
category: "api",
|
|
83
|
+
description: "Fetches weather data"
|
|
84
|
+
},
|
|
85
|
+
output: {
|
|
86
|
+
id: "tool-123",
|
|
87
|
+
name: "Weather API",
|
|
88
|
+
slug: "weather-api",
|
|
89
|
+
status: "draft"
|
|
90
|
+
}
|
|
91
|
+
}]
|
|
64
92
|
}
|
|
65
93
|
});
|
|
66
94
|
/**
|
|
@@ -119,6 +147,27 @@ const UpdateToolCommand = defineCommand({
|
|
|
119
147
|
payload: ToolSummaryModel
|
|
120
148
|
}],
|
|
121
149
|
audit: ["tool.updated"]
|
|
150
|
+
},
|
|
151
|
+
acceptance: {
|
|
152
|
+
scenarios: [{
|
|
153
|
+
key: "update-tool-happy-path",
|
|
154
|
+
given: ["Tool exists", "User owns the tool"],
|
|
155
|
+
when: ["User submits updated configuration"],
|
|
156
|
+
then: ["Tool is updated", "ToolUpdated event is emitted"]
|
|
157
|
+
}],
|
|
158
|
+
examples: [{
|
|
159
|
+
key: "update-description",
|
|
160
|
+
input: {
|
|
161
|
+
toolId: "tool-123",
|
|
162
|
+
description: "Updated weather API tool"
|
|
163
|
+
},
|
|
164
|
+
output: {
|
|
165
|
+
id: "tool-123",
|
|
166
|
+
name: "Weather API",
|
|
167
|
+
status: "draft",
|
|
168
|
+
updatedAt: "2025-01-01T00:00:00Z"
|
|
169
|
+
}
|
|
170
|
+
}]
|
|
122
171
|
}
|
|
123
172
|
});
|
|
124
173
|
/**
|
|
@@ -151,7 +200,25 @@ const GetToolQuery = defineQuery({
|
|
|
151
200
|
when: "Tool ID is invalid"
|
|
152
201
|
} }
|
|
153
202
|
},
|
|
154
|
-
policy: { auth: "user" }
|
|
203
|
+
policy: { auth: "user" },
|
|
204
|
+
acceptance: {
|
|
205
|
+
scenarios: [{
|
|
206
|
+
key: "get-tool-happy-path",
|
|
207
|
+
given: ["Tool exists"],
|
|
208
|
+
when: ["User requests tool by ID"],
|
|
209
|
+
then: ["Tool details are returned"]
|
|
210
|
+
}],
|
|
211
|
+
examples: [{
|
|
212
|
+
key: "get-basic",
|
|
213
|
+
input: { toolId: "tool-123" },
|
|
214
|
+
output: {
|
|
215
|
+
id: "tool-123",
|
|
216
|
+
name: "Weather API",
|
|
217
|
+
status: "active",
|
|
218
|
+
category: "api"
|
|
219
|
+
}
|
|
220
|
+
}]
|
|
221
|
+
}
|
|
155
222
|
});
|
|
156
223
|
/**
|
|
157
224
|
* ListToolsQuery - Lists tools for an organization.
|
|
@@ -218,7 +285,28 @@ const ListToolsQuery = defineQuery({
|
|
|
218
285
|
}
|
|
219
286
|
})
|
|
220
287
|
},
|
|
221
|
-
policy: { auth: "user" }
|
|
288
|
+
policy: { auth: "user" },
|
|
289
|
+
acceptance: {
|
|
290
|
+
scenarios: [{
|
|
291
|
+
key: "list-tools-happy-path",
|
|
292
|
+
given: ["Organization has tools"],
|
|
293
|
+
when: ["User lists tools"],
|
|
294
|
+
then: ["Paginated list of tools is returned"]
|
|
295
|
+
}],
|
|
296
|
+
examples: [{
|
|
297
|
+
key: "list-by-category",
|
|
298
|
+
input: {
|
|
299
|
+
organizationId: "org-123",
|
|
300
|
+
category: "api",
|
|
301
|
+
limit: 10
|
|
302
|
+
},
|
|
303
|
+
output: {
|
|
304
|
+
items: [],
|
|
305
|
+
total: 0,
|
|
306
|
+
hasMore: false
|
|
307
|
+
}
|
|
308
|
+
}]
|
|
309
|
+
}
|
|
222
310
|
});
|
|
223
311
|
/**
|
|
224
312
|
* TestToolCommand - Tests a tool with sample input.
|
|
@@ -285,7 +373,32 @@ const TestToolCommand = defineCommand({
|
|
|
285
373
|
}
|
|
286
374
|
},
|
|
287
375
|
policy: { auth: "user" },
|
|
288
|
-
sideEffects: { audit: ["tool.tested"] }
|
|
376
|
+
sideEffects: { audit: ["tool.tested"] },
|
|
377
|
+
acceptance: {
|
|
378
|
+
scenarios: [{
|
|
379
|
+
key: "test-tool-success",
|
|
380
|
+
given: ["Tool exists", "Tool is configured correctly"],
|
|
381
|
+
when: ["User runs test with valid input"],
|
|
382
|
+
then: ["Tool executes successfully", "Output is returned"]
|
|
383
|
+
}, {
|
|
384
|
+
key: "test-tool-failure",
|
|
385
|
+
given: ["Tool exists", "Tool has configuration error"],
|
|
386
|
+
when: ["User runs test"],
|
|
387
|
+
then: ["TOOL_EXECUTION_ERROR is returned"]
|
|
388
|
+
}],
|
|
389
|
+
examples: [{
|
|
390
|
+
key: "test-weather-api",
|
|
391
|
+
input: {
|
|
392
|
+
toolId: "tool-123",
|
|
393
|
+
testInput: { city: "Paris" }
|
|
394
|
+
},
|
|
395
|
+
output: {
|
|
396
|
+
success: true,
|
|
397
|
+
output: { temperature: 22 },
|
|
398
|
+
durationMs: 150
|
|
399
|
+
}
|
|
400
|
+
}]
|
|
401
|
+
}
|
|
289
402
|
});
|
|
290
403
|
|
|
291
404
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.operation.js","names":[],"sources":["../../src/tool/tool.operation.ts"],"sourcesContent":["import { defineCommand, defineQuery } from '@lssm/lib.contracts/operations';\nimport { defineSchemaModel, ScalarTypeEnum } from '@lssm/lib.schema';\nimport { ToolCategoryEnum, ToolStatusEnum } from './tool.enum';\nimport {\n CreateToolInputModel,\n ToolModel,\n ToolSummaryModel,\n UpdateToolInputModel,\n} from './tool.schema';\n\nconst OWNERS = ['@agent-console-team'] as const;\n\n/**\n * CreateToolCommand - Creates a new tool definition.\n */\nexport const CreateToolCommand = defineCommand({\n meta: {\n key: 'agent.tool.create',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'create'],\n description: 'Creates a new AI tool definition.',\n goal: 'Allow users to define new tools that agents can use.',\n context: 'Called from the tool builder UI when creating a new tool.',\n },\n io: {\n input: CreateToolInputModel,\n output: defineSchemaModel({\n name: 'CreateToolOutput',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },\n slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n status: { type: ToolStatusEnum, isOptional: false },\n },\n }),\n errors: {\n SLUG_EXISTS: {\n description: 'A tool with this slug already exists in the organization',\n http: 409,\n gqlCode: 'SLUG_EXISTS',\n when: 'Slug is already taken',\n },\n },\n },\n policy: { auth: 'user' },\n sideEffects: {\n emits: [\n {\n key: 'tool.created',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'created'],\n when: 'Tool is successfully created',\n payload: ToolSummaryModel,\n },\n ],\n audit: ['tool.created'],\n },\n});\n\n/**\n * UpdateToolCommand - Updates an existing tool.\n */\nexport const UpdateToolCommand = defineCommand({\n meta: {\n key: 'agent.tool.update',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'update'],\n description: 'Updates an existing AI tool definition.',\n goal: 'Allow users to modify tool settings and configuration.',\n context: 'Called from the tool settings UI.',\n },\n io: {\n input: UpdateToolInputModel,\n output: defineSchemaModel({\n name: 'UpdateToolOutput',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },\n status: { type: ToolStatusEnum, isOptional: false },\n updatedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n }),\n errors: {\n TOOL_NOT_FOUND: {\n description: 'The specified tool does not exist',\n http: 404,\n gqlCode: 'TOOL_NOT_FOUND',\n when: 'Tool ID is invalid',\n },\n },\n },\n policy: { auth: 'user' },\n sideEffects: {\n emits: [\n {\n key: 'tool.updated',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'updated'],\n when: 'Tool is updated',\n payload: ToolSummaryModel,\n },\n ],\n audit: ['tool.updated'],\n },\n});\n\n/**\n * GetToolQuery - Retrieves a tool by ID.\n */\nexport const GetToolQuery = defineQuery({\n meta: {\n key: 'agent.tool.get',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'get'],\n description: 'Retrieves a tool by its ID.',\n goal: 'View detailed tool configuration.',\n context: 'Called when viewing tool details or editing.',\n },\n io: {\n input: defineSchemaModel({\n name: 'GetToolInput',\n fields: {\n toolId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n }),\n output: ToolModel,\n errors: {\n TOOL_NOT_FOUND: {\n description: 'The specified tool does not exist',\n http: 404,\n gqlCode: 'TOOL_NOT_FOUND',\n when: 'Tool ID is invalid',\n },\n },\n },\n policy: { auth: 'user' },\n});\n\n/**\n * ListToolsQuery - Lists tools for an organization.\n */\nexport const ListToolsQuery = defineQuery({\n meta: {\n key: 'agent.tool.list',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'list'],\n description: 'Lists tools for an organization with optional filtering.',\n goal: 'Browse and search available tools.',\n context: 'Tool list/dashboard view.',\n },\n io: {\n input: defineSchemaModel({\n name: 'ListToolsInput',\n fields: {\n organizationId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n category: { type: ToolCategoryEnum, isOptional: true },\n status: { type: ToolStatusEnum, isOptional: true },\n search: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n limit: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n defaultValue: 20,\n },\n offset: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n defaultValue: 0,\n },\n },\n }),\n output: defineSchemaModel({\n name: 'ListToolsOutput',\n fields: {\n items: { type: ToolSummaryModel, isArray: true, isOptional: false },\n total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n hasMore: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n },\n }),\n },\n policy: { auth: 'user' },\n});\n\n/**\n * TestToolCommand - Tests a tool with sample input.\n */\nexport const TestToolCommand = defineCommand({\n meta: {\n key: 'agent.tool.test',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'test'],\n description: 'Tests a tool with sample input to verify it works correctly.',\n goal: 'Validate tool configuration before deployment.',\n context: 'Tool builder UI - test panel.',\n },\n io: {\n input: defineSchemaModel({\n name: 'TestToolInput',\n fields: {\n toolId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n testInput: { type: ScalarTypeEnum.JSONObject(), isOptional: false },\n },\n }),\n output: defineSchemaModel({\n name: 'TestToolOutput',\n fields: {\n success: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n output: { type: ScalarTypeEnum.JSONObject(), isOptional: true },\n error: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n durationMs: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n },\n }),\n errors: {\n TOOL_NOT_FOUND: {\n description: 'The specified tool does not exist',\n http: 404,\n gqlCode: 'TOOL_NOT_FOUND',\n when: 'Tool ID is invalid',\n },\n TOOL_EXECUTION_ERROR: {\n description: 'Tool execution failed',\n http: 500,\n gqlCode: 'TOOL_EXECUTION_ERROR',\n when: 'Tool returns an error',\n },\n },\n },\n policy: { auth: 'user' },\n sideEffects: { audit: ['tool.tested'] },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tool.operation.js","names":[],"sources":["../../src/tool/tool.operation.ts"],"sourcesContent":["import { defineCommand, defineQuery } from '@lssm/lib.contracts/operations';\nimport { defineSchemaModel, ScalarTypeEnum } from '@lssm/lib.schema';\nimport { ToolCategoryEnum, ToolStatusEnum } from './tool.enum';\nimport {\n CreateToolInputModel,\n ToolModel,\n ToolSummaryModel,\n UpdateToolInputModel,\n} from './tool.schema';\n\nconst OWNERS = ['@agent-console-team'] as const;\n\n/**\n * CreateToolCommand - Creates a new tool definition.\n */\nexport const CreateToolCommand = defineCommand({\n meta: {\n key: 'agent.tool.create',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'create'],\n description: 'Creates a new AI tool definition.',\n goal: 'Allow users to define new tools that agents can use.',\n context: 'Called from the tool builder UI when creating a new tool.',\n },\n io: {\n input: CreateToolInputModel,\n output: defineSchemaModel({\n name: 'CreateToolOutput',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },\n slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n status: { type: ToolStatusEnum, isOptional: false },\n },\n }),\n errors: {\n SLUG_EXISTS: {\n description: 'A tool with this slug already exists in the organization',\n http: 409,\n gqlCode: 'SLUG_EXISTS',\n when: 'Slug is already taken',\n },\n },\n },\n policy: { auth: 'user' },\n sideEffects: {\n emits: [\n {\n key: 'tool.created',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'created'],\n when: 'Tool is successfully created',\n payload: ToolSummaryModel,\n },\n ],\n audit: ['tool.created'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'create-tool-happy-path',\n given: ['User is authenticated', 'Organization exists'],\n when: ['User submits valid tool configuration'],\n then: ['New tool is created', 'ToolCreated event is emitted'],\n },\n {\n key: 'create-tool-slug-conflict',\n given: ['Tool with same slug exists'],\n when: ['User submits tool with duplicate slug'],\n then: ['SLUG_EXISTS error is returned'],\n },\n ],\n examples: [\n {\n key: 'create-api-tool',\n input: { name: 'Weather API', slug: 'weather-api', category: 'api', description: 'Fetches weather data' },\n output: { id: 'tool-123', name: 'Weather API', slug: 'weather-api', status: 'draft' },\n },\n ],\n },\n});\n\n/**\n * UpdateToolCommand - Updates an existing tool.\n */\nexport const UpdateToolCommand = defineCommand({\n meta: {\n key: 'agent.tool.update',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'update'],\n description: 'Updates an existing AI tool definition.',\n goal: 'Allow users to modify tool settings and configuration.',\n context: 'Called from the tool settings UI.',\n },\n io: {\n input: UpdateToolInputModel,\n output: defineSchemaModel({\n name: 'UpdateToolOutput',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },\n status: { type: ToolStatusEnum, isOptional: false },\n updatedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n }),\n errors: {\n TOOL_NOT_FOUND: {\n description: 'The specified tool does not exist',\n http: 404,\n gqlCode: 'TOOL_NOT_FOUND',\n when: 'Tool ID is invalid',\n },\n },\n },\n policy: { auth: 'user' },\n sideEffects: {\n emits: [\n {\n key: 'tool.updated',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'updated'],\n when: 'Tool is updated',\n payload: ToolSummaryModel,\n },\n ],\n audit: ['tool.updated'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'update-tool-happy-path',\n given: ['Tool exists', 'User owns the tool'],\n when: ['User submits updated configuration'],\n then: ['Tool is updated', 'ToolUpdated event is emitted'],\n },\n ],\n examples: [\n {\n key: 'update-description',\n input: { toolId: 'tool-123', description: 'Updated weather API tool' },\n output: { id: 'tool-123', name: 'Weather API', status: 'draft', updatedAt: '2025-01-01T00:00:00Z' },\n },\n ],\n },\n});\n\n/**\n * GetToolQuery - Retrieves a tool by ID.\n */\nexport const GetToolQuery = defineQuery({\n meta: {\n key: 'agent.tool.get',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'get'],\n description: 'Retrieves a tool by its ID.',\n goal: 'View detailed tool configuration.',\n context: 'Called when viewing tool details or editing.',\n },\n io: {\n input: defineSchemaModel({\n name: 'GetToolInput',\n fields: {\n toolId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n }),\n output: ToolModel,\n errors: {\n TOOL_NOT_FOUND: {\n description: 'The specified tool does not exist',\n http: 404,\n gqlCode: 'TOOL_NOT_FOUND',\n when: 'Tool ID is invalid',\n },\n },\n },\n policy: { auth: 'user' },\n acceptance: {\n scenarios: [\n {\n key: 'get-tool-happy-path',\n given: ['Tool exists'],\n when: ['User requests tool by ID'],\n then: ['Tool details are returned'],\n },\n ],\n examples: [\n {\n key: 'get-basic',\n input: { toolId: 'tool-123' },\n output: { id: 'tool-123', name: 'Weather API', status: 'active', category: 'api' },\n },\n ],\n },\n});\n\n/**\n * ListToolsQuery - Lists tools for an organization.\n */\nexport const ListToolsQuery = defineQuery({\n meta: {\n key: 'agent.tool.list',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'list'],\n description: 'Lists tools for an organization with optional filtering.',\n goal: 'Browse and search available tools.',\n context: 'Tool list/dashboard view.',\n },\n io: {\n input: defineSchemaModel({\n name: 'ListToolsInput',\n fields: {\n organizationId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n category: { type: ToolCategoryEnum, isOptional: true },\n status: { type: ToolStatusEnum, isOptional: true },\n search: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n limit: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n defaultValue: 20,\n },\n offset: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n defaultValue: 0,\n },\n },\n }),\n output: defineSchemaModel({\n name: 'ListToolsOutput',\n fields: {\n items: { type: ToolSummaryModel, isArray: true, isOptional: false },\n total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n hasMore: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n },\n }),\n },\n policy: { auth: 'user' },\n acceptance: {\n scenarios: [\n {\n key: 'list-tools-happy-path',\n given: ['Organization has tools'],\n when: ['User lists tools'],\n then: ['Paginated list of tools is returned'],\n },\n ],\n examples: [\n {\n key: 'list-by-category',\n input: { organizationId: 'org-123', category: 'api', limit: 10 },\n output: { items: [], total: 0, hasMore: false },\n },\n ],\n },\n});\n\n/**\n * TestToolCommand - Tests a tool with sample input.\n */\nexport const TestToolCommand = defineCommand({\n meta: {\n key: 'agent.tool.test',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['tool', 'test'],\n description: 'Tests a tool with sample input to verify it works correctly.',\n goal: 'Validate tool configuration before deployment.',\n context: 'Tool builder UI - test panel.',\n },\n io: {\n input: defineSchemaModel({\n name: 'TestToolInput',\n fields: {\n toolId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n testInput: { type: ScalarTypeEnum.JSONObject(), isOptional: false },\n },\n }),\n output: defineSchemaModel({\n name: 'TestToolOutput',\n fields: {\n success: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n output: { type: ScalarTypeEnum.JSONObject(), isOptional: true },\n error: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n durationMs: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n },\n }),\n errors: {\n TOOL_NOT_FOUND: {\n description: 'The specified tool does not exist',\n http: 404,\n gqlCode: 'TOOL_NOT_FOUND',\n when: 'Tool ID is invalid',\n },\n TOOL_EXECUTION_ERROR: {\n description: 'Tool execution failed',\n http: 500,\n gqlCode: 'TOOL_EXECUTION_ERROR',\n when: 'Tool returns an error',\n },\n },\n },\n policy: { auth: 'user' },\n sideEffects: { audit: ['tool.tested'] },\n acceptance: {\n scenarios: [\n {\n key: 'test-tool-success',\n given: ['Tool exists', 'Tool is configured correctly'],\n when: ['User runs test with valid input'],\n then: ['Tool executes successfully', 'Output is returned'],\n },\n {\n key: 'test-tool-failure',\n given: ['Tool exists', 'Tool has configuration error'],\n when: ['User runs test'],\n then: ['TOOL_EXECUTION_ERROR is returned'],\n },\n ],\n examples: [\n {\n key: 'test-weather-api',\n input: { toolId: 'tool-123', testInput: { city: 'Paris' } },\n output: { success: true, output: { temperature: 22 }, durationMs: 150 },\n },\n ],\n },\n});\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.presentation.d.ts","names":[],"sources":["../../src/tool/tool.presentation.ts"],"sourcesContent":[],"mappings":";;;;;;AAOA;AA2Ba,cA3BA,
|
|
1
|
+
{"version":3,"file":"tool.presentation.d.ts","names":[],"sources":["../../src/tool/tool.presentation.ts"],"sourcesContent":[],"mappings":";;;;;;AAOA;AA2Ba,cA3BA,oBA2BwB,EA3BF,gBAgDlC;;;;cArBY,wBAAwB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lssm/example.agent-console",
|
|
3
|
-
"version": "0.0.0-canary-
|
|
3
|
+
"version": "0.0.0-canary-20251225052113",
|
|
4
4
|
"description": "Agent Console example - AI agent orchestration with tools, runs, and logs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -57,17 +57,17 @@
|
|
|
57
57
|
"test": "bun run"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@lssm/lib.schema": "0.0.0-canary-
|
|
61
|
-
"@lssm/lib.contracts": "0.0.0-canary-
|
|
62
|
-
"@lssm/lib.identity-rbac": "0.0.0-canary-
|
|
63
|
-
"@lssm/module.audit-trail": "0.0.0-canary-
|
|
64
|
-
"@lssm/lib.jobs": "0.0.0-canary-
|
|
60
|
+
"@lssm/lib.schema": "0.0.0-canary-20251225052113",
|
|
61
|
+
"@lssm/lib.contracts": "0.0.0-canary-20251225052113",
|
|
62
|
+
"@lssm/lib.identity-rbac": "0.0.0-canary-20251225052113",
|
|
63
|
+
"@lssm/module.audit-trail": "0.0.0-canary-20251225052113",
|
|
64
|
+
"@lssm/lib.jobs": "0.0.0-canary-20251225052113",
|
|
65
65
|
"zod": "^4.1.13"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@lssm/tool.tsdown": "0.0.0-canary-
|
|
69
|
-
"@lssm/tool.typescript": "0.0.0-canary-
|
|
70
|
-
"tsdown": "^0.18.
|
|
68
|
+
"@lssm/tool.tsdown": "0.0.0-canary-20251225052113",
|
|
69
|
+
"@lssm/tool.typescript": "0.0.0-canary-20251225052113",
|
|
70
|
+
"tsdown": "^0.18.3",
|
|
71
71
|
"typescript": "^5.9.3"
|
|
72
72
|
},
|
|
73
73
|
"module": "./dist/index.js",
|
|
@@ -59,6 +59,29 @@ export const CreateAgentCommand = defineCommand({
|
|
|
59
59
|
],
|
|
60
60
|
audit: ['agent-console.agent.created'],
|
|
61
61
|
},
|
|
62
|
+
acceptance: {
|
|
63
|
+
scenarios: [
|
|
64
|
+
{
|
|
65
|
+
key: 'create-agent-happy-path',
|
|
66
|
+
given: ['User is authenticated', 'Organization exists'],
|
|
67
|
+
when: ['User submits valid agent configuration'],
|
|
68
|
+
then: ['New agent is created with DRAFT status', 'AgentCreated event is emitted'],
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
key: 'create-agent-slug-conflict',
|
|
72
|
+
given: ['User is authenticated', 'Agent with same slug exists'],
|
|
73
|
+
when: ['User submits agent with duplicate slug'],
|
|
74
|
+
then: ['SLUG_EXISTS error is returned with 409 status'],
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
examples: [
|
|
78
|
+
{
|
|
79
|
+
key: 'basic-create',
|
|
80
|
+
input: { name: 'Support Assistant', slug: 'support-assistant', modelProvider: 'openai', modelId: 'gpt-4' },
|
|
81
|
+
output: { id: 'agent-123', name: 'Support Assistant', slug: 'support-assistant', status: 'draft' },
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
},
|
|
62
85
|
});
|
|
63
86
|
|
|
64
87
|
/**
|
|
@@ -110,6 +133,29 @@ export const UpdateAgentCommand = defineCommand({
|
|
|
110
133
|
],
|
|
111
134
|
audit: ['agent.updated'],
|
|
112
135
|
},
|
|
136
|
+
acceptance: {
|
|
137
|
+
scenarios: [
|
|
138
|
+
{
|
|
139
|
+
key: 'update-agent-happy-path',
|
|
140
|
+
given: ['Agent exists', 'User owns the agent'],
|
|
141
|
+
when: ['User submits updated configuration'],
|
|
142
|
+
then: ['Agent is updated', 'AgentUpdated event is emitted'],
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
key: 'update-agent-not-found',
|
|
146
|
+
given: ['Agent does not exist'],
|
|
147
|
+
when: ['User attempts to update'],
|
|
148
|
+
then: ['AGENT_NOT_FOUND error is returned'],
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
examples: [
|
|
152
|
+
{
|
|
153
|
+
key: 'update-name',
|
|
154
|
+
input: { agentId: 'agent-123', name: 'Updated Assistant', systemPrompt: 'You are a helpful assistant.' },
|
|
155
|
+
output: { id: 'agent-123', name: 'Updated Assistant', status: 'draft', updatedAt: '2025-01-01T00:00:00Z' },
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
},
|
|
113
159
|
});
|
|
114
160
|
|
|
115
161
|
/**
|
|
@@ -145,6 +191,29 @@ export const GetAgentQuery = defineQuery({
|
|
|
145
191
|
},
|
|
146
192
|
},
|
|
147
193
|
policy: { auth: 'user' },
|
|
194
|
+
acceptance: {
|
|
195
|
+
scenarios: [
|
|
196
|
+
{
|
|
197
|
+
key: 'get-agent-happy-path',
|
|
198
|
+
given: ['Agent exists'],
|
|
199
|
+
when: ['User requests agent by ID'],
|
|
200
|
+
then: ['Agent details are returned'],
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
key: 'get-agent-with-tools',
|
|
204
|
+
given: ['Agent exists with assigned tools'],
|
|
205
|
+
when: ['User requests agent with includeTools=true'],
|
|
206
|
+
then: ['Agent details with tools list are returned'],
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
examples: [
|
|
210
|
+
{
|
|
211
|
+
key: 'get-basic',
|
|
212
|
+
input: { agentId: 'agent-123', includeTools: false },
|
|
213
|
+
output: { id: 'agent-123', name: 'Support Assistant', status: 'active', tools: [] },
|
|
214
|
+
},
|
|
215
|
+
],
|
|
216
|
+
},
|
|
148
217
|
});
|
|
149
218
|
|
|
150
219
|
/**
|
|
@@ -194,6 +263,29 @@ export const ListAgentsQuery = defineQuery({
|
|
|
194
263
|
}),
|
|
195
264
|
},
|
|
196
265
|
policy: { auth: 'user' },
|
|
266
|
+
acceptance: {
|
|
267
|
+
scenarios: [
|
|
268
|
+
{
|
|
269
|
+
key: 'list-agents-happy-path',
|
|
270
|
+
given: ['Organization has agents'],
|
|
271
|
+
when: ['User lists agents'],
|
|
272
|
+
then: ['Paginated list of agents is returned'],
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
key: 'list-agents-filter-by-status',
|
|
276
|
+
given: ['Organization has agents with mixed statuses'],
|
|
277
|
+
when: ['User filters by status=active'],
|
|
278
|
+
then: ['Only active agents are returned'],
|
|
279
|
+
},
|
|
280
|
+
],
|
|
281
|
+
examples: [
|
|
282
|
+
{
|
|
283
|
+
key: 'list-basic',
|
|
284
|
+
input: { organizationId: 'org-123', limit: 10, offset: 0 },
|
|
285
|
+
output: { items: [], total: 0, hasMore: false },
|
|
286
|
+
},
|
|
287
|
+
],
|
|
288
|
+
},
|
|
197
289
|
});
|
|
198
290
|
|
|
199
291
|
/**
|
|
@@ -242,6 +334,29 @@ export const AssignToolToAgentCommand = defineCommand({
|
|
|
242
334
|
},
|
|
243
335
|
policy: { auth: 'user' },
|
|
244
336
|
sideEffects: { audit: ['agent.tool.assigned'] },
|
|
337
|
+
acceptance: {
|
|
338
|
+
scenarios: [
|
|
339
|
+
{
|
|
340
|
+
key: 'assign-tool-happy-path',
|
|
341
|
+
given: ['Agent exists', 'Tool exists and is not assigned'],
|
|
342
|
+
when: ['User assigns tool to agent'],
|
|
343
|
+
then: ['Tool is assigned', 'Assignment ID is returned'],
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
key: 'assign-tool-already-assigned',
|
|
347
|
+
given: ['Tool is already assigned to agent'],
|
|
348
|
+
when: ['User attempts to assign again'],
|
|
349
|
+
then: ['TOOL_ALREADY_ASSIGNED error is returned'],
|
|
350
|
+
},
|
|
351
|
+
],
|
|
352
|
+
examples: [
|
|
353
|
+
{
|
|
354
|
+
key: 'assign-basic',
|
|
355
|
+
input: { agentId: 'agent-123', toolId: 'tool-456' },
|
|
356
|
+
output: { agentToolId: 'at-789', agentId: 'agent-123', toolId: 'tool-456' },
|
|
357
|
+
},
|
|
358
|
+
],
|
|
359
|
+
},
|
|
245
360
|
});
|
|
246
361
|
|
|
247
362
|
/**
|
|
@@ -275,4 +390,21 @@ export const RemoveToolFromAgentCommand = defineCommand({
|
|
|
275
390
|
},
|
|
276
391
|
policy: { auth: 'user' },
|
|
277
392
|
sideEffects: { audit: ['agent.tool.removed'] },
|
|
393
|
+
acceptance: {
|
|
394
|
+
scenarios: [
|
|
395
|
+
{
|
|
396
|
+
key: 'remove-tool-happy-path',
|
|
397
|
+
given: ['Agent exists', 'Tool is assigned to agent'],
|
|
398
|
+
when: ['User removes tool from agent'],
|
|
399
|
+
then: ['Tool is unassigned', 'Success is returned'],
|
|
400
|
+
},
|
|
401
|
+
],
|
|
402
|
+
examples: [
|
|
403
|
+
{
|
|
404
|
+
key: 'remove-basic',
|
|
405
|
+
input: { agentId: 'agent-123', toolId: 'tool-456' },
|
|
406
|
+
output: { success: true },
|
|
407
|
+
},
|
|
408
|
+
],
|
|
409
|
+
},
|
|
278
410
|
});
|
package/src/run/run.operation.ts
CHANGED
|
@@ -83,6 +83,29 @@ export const ExecuteAgentCommand = defineCommand({
|
|
|
83
83
|
],
|
|
84
84
|
audit: ['run.started'],
|
|
85
85
|
},
|
|
86
|
+
acceptance: {
|
|
87
|
+
scenarios: [
|
|
88
|
+
{
|
|
89
|
+
key: 'execute-agent-happy-path',
|
|
90
|
+
given: ['Agent exists', 'Agent is active'],
|
|
91
|
+
when: ['User submits execution request'],
|
|
92
|
+
then: ['Run is created', 'RunStarted event is emitted'],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
key: 'execute-agent-not-active',
|
|
96
|
+
given: ['Agent exists but is not active'],
|
|
97
|
+
when: ['User attempts to execute'],
|
|
98
|
+
then: ['AGENT_NOT_ACTIVE error is returned'],
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
examples: [
|
|
102
|
+
{
|
|
103
|
+
key: 'basic-execute',
|
|
104
|
+
input: { agentId: 'agent-123', input: { message: 'Hello' } },
|
|
105
|
+
output: { runId: 'run-456', status: 'pending', estimatedWaitMs: 5000 },
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
},
|
|
86
109
|
});
|
|
87
110
|
|
|
88
111
|
/**
|
|
@@ -144,6 +167,29 @@ export const CancelRunCommand = defineCommand({
|
|
|
144
167
|
],
|
|
145
168
|
audit: ['run.cancelled'],
|
|
146
169
|
},
|
|
170
|
+
acceptance: {
|
|
171
|
+
scenarios: [
|
|
172
|
+
{
|
|
173
|
+
key: 'cancel-run-happy-path',
|
|
174
|
+
given: ['Run exists', 'Run is in progress'],
|
|
175
|
+
when: ['User cancels run'],
|
|
176
|
+
then: ['Run is cancelled', 'RunCancelled event is emitted'],
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
key: 'cancel-run-already-completed',
|
|
180
|
+
given: ['Run exists but is already completed'],
|
|
181
|
+
when: ['User attempts to cancel'],
|
|
182
|
+
then: ['RUN_NOT_CANCELLABLE error is returned'],
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
examples: [
|
|
186
|
+
{
|
|
187
|
+
key: 'cancel-basic',
|
|
188
|
+
input: { runId: 'run-456', reason: 'User requested' },
|
|
189
|
+
output: { success: true, status: 'cancelled' },
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
},
|
|
147
193
|
});
|
|
148
194
|
|
|
149
195
|
/**
|
|
@@ -180,6 +226,23 @@ export const GetRunQuery = defineQuery({
|
|
|
180
226
|
},
|
|
181
227
|
},
|
|
182
228
|
policy: { auth: 'user' },
|
|
229
|
+
acceptance: {
|
|
230
|
+
scenarios: [
|
|
231
|
+
{
|
|
232
|
+
key: 'get-run-happy-path',
|
|
233
|
+
given: ['Run exists'],
|
|
234
|
+
when: ['User requests run by ID'],
|
|
235
|
+
then: ['Run details are returned'],
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
examples: [
|
|
239
|
+
{
|
|
240
|
+
key: 'get-with-steps',
|
|
241
|
+
input: { runId: 'run-456', includeSteps: true, includeLogs: false },
|
|
242
|
+
output: { id: 'run-456', status: 'completed', steps: [] },
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
},
|
|
183
246
|
});
|
|
184
247
|
|
|
185
248
|
/**
|
|
@@ -232,6 +295,23 @@ export const ListRunsQuery = defineQuery({
|
|
|
232
295
|
}),
|
|
233
296
|
},
|
|
234
297
|
policy: { auth: 'user' },
|
|
298
|
+
acceptance: {
|
|
299
|
+
scenarios: [
|
|
300
|
+
{
|
|
301
|
+
key: 'list-runs-happy-path',
|
|
302
|
+
given: ['Organization has runs'],
|
|
303
|
+
when: ['User lists runs'],
|
|
304
|
+
then: ['Paginated list of runs is returned'],
|
|
305
|
+
},
|
|
306
|
+
],
|
|
307
|
+
examples: [
|
|
308
|
+
{
|
|
309
|
+
key: 'list-by-agent',
|
|
310
|
+
input: { agentId: 'agent-123', limit: 20, offset: 0 },
|
|
311
|
+
output: { items: [], total: 0, hasMore: false },
|
|
312
|
+
},
|
|
313
|
+
],
|
|
314
|
+
},
|
|
235
315
|
});
|
|
236
316
|
|
|
237
317
|
/**
|
|
@@ -263,6 +343,23 @@ export const GetRunStepsQuery = defineQuery({
|
|
|
263
343
|
}),
|
|
264
344
|
},
|
|
265
345
|
policy: { auth: 'user' },
|
|
346
|
+
acceptance: {
|
|
347
|
+
scenarios: [
|
|
348
|
+
{
|
|
349
|
+
key: 'get-run-steps-happy-path',
|
|
350
|
+
given: ['Run exists with steps'],
|
|
351
|
+
when: ['User requests steps'],
|
|
352
|
+
then: ['Steps list is returned'],
|
|
353
|
+
},
|
|
354
|
+
],
|
|
355
|
+
examples: [
|
|
356
|
+
{
|
|
357
|
+
key: 'get-steps-basic',
|
|
358
|
+
input: { runId: 'run-456' },
|
|
359
|
+
output: { steps: [] },
|
|
360
|
+
},
|
|
361
|
+
],
|
|
362
|
+
},
|
|
266
363
|
});
|
|
267
364
|
|
|
268
365
|
/**
|
|
@@ -308,6 +405,23 @@ export const GetRunLogsQuery = defineQuery({
|
|
|
308
405
|
}),
|
|
309
406
|
},
|
|
310
407
|
policy: { auth: 'user' },
|
|
408
|
+
acceptance: {
|
|
409
|
+
scenarios: [
|
|
410
|
+
{
|
|
411
|
+
key: 'get-run-logs-happy-path',
|
|
412
|
+
given: ['Run exists with logs'],
|
|
413
|
+
when: ['User requests logs'],
|
|
414
|
+
then: ['Paginated logs list is returned'],
|
|
415
|
+
},
|
|
416
|
+
],
|
|
417
|
+
examples: [
|
|
418
|
+
{
|
|
419
|
+
key: 'get-logs-filtered',
|
|
420
|
+
input: { runId: 'run-456', level: 'error', limit: 50 },
|
|
421
|
+
output: { items: [], total: 0, hasMore: false },
|
|
422
|
+
},
|
|
423
|
+
],
|
|
424
|
+
},
|
|
311
425
|
});
|
|
312
426
|
|
|
313
427
|
/**
|
|
@@ -373,4 +487,21 @@ export const GetRunMetricsQuery = defineQuery({
|
|
|
373
487
|
}),
|
|
374
488
|
},
|
|
375
489
|
policy: { auth: 'user' },
|
|
490
|
+
acceptance: {
|
|
491
|
+
scenarios: [
|
|
492
|
+
{
|
|
493
|
+
key: 'get-run-metrics-happy-path',
|
|
494
|
+
given: ['Organization has run history'],
|
|
495
|
+
when: ['User requests metrics for date range'],
|
|
496
|
+
then: ['Aggregated metrics are returned'],
|
|
497
|
+
},
|
|
498
|
+
],
|
|
499
|
+
examples: [
|
|
500
|
+
{
|
|
501
|
+
key: 'get-daily-metrics',
|
|
502
|
+
input: { organizationId: 'org-123', startDate: '2025-01-01', endDate: '2025-01-31', granularity: 'day' },
|
|
503
|
+
output: { totalRuns: 100, completedRuns: 90, failedRuns: 10, totalTokens: 50000, totalCostUsd: 5.0, averageDurationMs: 2500, successRate: 0.9, timeline: [] },
|
|
504
|
+
},
|
|
505
|
+
],
|
|
506
|
+
},
|
|
376
507
|
});
|