@anteros/core 0.0.41 → 0.0.42

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 (102) hide show
  1. package/database/audit.ts +9 -59
  2. package/database/collection.ts +3 -1
  3. package/database/deleteLog.ts +67 -3
  4. package/database/file.ts +4 -3
  5. package/database/mongodbadapter.ts +103 -42
  6. package/database/replication.ts +110 -32
  7. package/database/ttl.ts +68 -0
  8. package/database/workflow.ts +466 -240
  9. package/index.ts +6 -0
  10. package/lib/agent.ts +1327 -0
  11. package/lib/agentMemory.ts +586 -0
  12. package/lib/agents.ts +157 -0
  13. package/lib/ai.ts +0 -0
  14. package/lib/api.ts +246 -0
  15. package/lib/attachment.ts +351 -0
  16. package/lib/auditResult.ts +13 -0
  17. package/lib/define.ts +43 -1
  18. package/lib/endpoints.ts +80 -0
  19. package/lib/files.ts +2 -1
  20. package/lib/jsonSchema.ts +183 -0
  21. package/lib/lifecycle.ts +7 -1
  22. package/lib/load.ts +17 -0
  23. package/lib/mcp.ts +3 -2
  24. package/lib/messages.ts +299 -0
  25. package/lib/providers.ts +867 -0
  26. package/lib/routes.ts +14 -1
  27. package/lib/scriptWorker.ts +4 -1
  28. package/lib/scripts.ts +6 -1
  29. package/lib/sockets.ts +3 -1
  30. package/lib/workflow.ts +209 -37
  31. package/lib/zip.ts +109 -0
  32. package/package.json +1 -1
  33. package/server/access.ts +96 -0
  34. package/server/agents.ts +451 -0
  35. package/server/api.ts +14 -72
  36. package/server/boot.ts +11 -0
  37. package/server/hono.ts +8 -3
  38. package/server/mcp.ts +17 -63
  39. package/server/routes.ts +19 -24
  40. package/tests/agent-memory.test.ts +617 -0
  41. package/tests/agent-working-memory.test.ts +402 -0
  42. package/tests/agent.test.ts +1239 -0
  43. package/tests/agents-api.test.ts +593 -0
  44. package/tests/api.test.ts +51 -0
  45. package/tests/attachment.test.ts +241 -0
  46. package/tests/audit-operations.test.ts +1 -1
  47. package/tests/audit-redact.test.ts +29 -3
  48. package/tests/audit-run-action.test.ts +1 -1
  49. package/tests/endpoints.test.ts +80 -0
  50. package/tests/fixtures/agent-tenant/agents/support.agent.ts +9 -0
  51. package/tests/fixtures/agent-tenant/agents/weather.agent.ts +21 -0
  52. package/tests/fixtures/agents-api/agents/assistant.agent.ts +46 -0
  53. package/tests/fixtures/agents-api/agents/plain.agent.ts +23 -0
  54. package/tests/fixtures/agents-api/agents/private.agent.ts +15 -0
  55. package/tests/fixtures/agents-api/collections/notes.model.ts +26 -0
  56. package/tests/fixtures/agents-api/routes/probe.route.ts +21 -0
  57. package/tests/fixtures/agents-api/services/probe.service.ts +19 -0
  58. package/tests/fixtures/attachment/data.csv +2 -0
  59. package/tests/fixtures/fake-provider.ts +128 -0
  60. package/tests/fixtures/replication-meta/agents/chat.agent.ts +16 -0
  61. package/tests/fixtures/replication-meta/collections/counters.model.ts +13 -0
  62. package/tests/fixtures/replication-meta/collections/orders.model.ts +9 -0
  63. package/tests/fixtures/replication-meta/workflows/run.workflow.ts +8 -0
  64. package/tests/fixtures/vars-tenant/vars/private.var.ts +4 -1
  65. package/tests/fixtures/workflow-engine/workflows/failing.workflow.ts +34 -0
  66. package/tests/fixtures/workflow-engine/workflows/flaky.workflow.ts +23 -0
  67. package/tests/fixtures/workflow-engine/workflows/hang.workflow.ts +17 -0
  68. package/tests/fixtures/workflow-engine/workflows/simple.workflow.ts +19 -0
  69. package/tests/fixtures/workflow-engine/workflows/slow.workflow.ts +23 -0
  70. package/tests/fixtures/workflow-engine/workflows/versioned.workflow.ts +19 -0
  71. package/tests/fixtures/workflow-tenant/workflows/broken.workflow.ts +3 -0
  72. package/tests/fixtures/workflow-tenant/workflows/disabled.workflow.ts +8 -0
  73. package/tests/fixtures/workflow-tenant/workflows/invoice.workflow.ts +21 -0
  74. package/tests/fixtures/workflow-tenant/workflows/no-id.workflow.ts +7 -0
  75. package/tests/fixtures/workflow-tenant/workflows/order-duplicate.workflow.ts +13 -0
  76. package/tests/fixtures/workflow-tenant/workflows/order.workflow.ts +17 -0
  77. package/tests/hono.test.ts +6 -3
  78. package/tests/locks.test.ts +120 -0
  79. package/tests/mcp.test.ts +11 -11
  80. package/tests/messages.test.ts +258 -0
  81. package/tests/replication-control.test.ts +2 -2
  82. package/tests/replication-meta.test.ts +243 -0
  83. package/tests/upload.test.ts +44 -12
  84. package/tests/vars-api.test.ts +1 -1
  85. package/tests/vars-replication.test.ts +3 -2
  86. package/tests/workflow-engine.test.ts +340 -0
  87. package/tests/workflow-retention.test.ts +103 -0
  88. package/tests/workflow.test.ts +186 -0
  89. package/types/agent.d.ts +837 -0
  90. package/types/config.d.ts +16 -0
  91. package/types/file.d.ts +7 -7
  92. package/types/hook.d.ts +6 -0
  93. package/types/lifecycle.d.ts +6 -0
  94. package/types/mcp.d.ts +11 -1
  95. package/types/replication.d.ts +29 -0
  96. package/types/route.d.ts +7 -1
  97. package/types/scripts.d.ts +6 -0
  98. package/types/service.d.ts +7 -1
  99. package/types/tenant.d.ts +13 -0
  100. package/types/vars.d.ts +2 -2
  101. package/types/websocket.d.ts +6 -0
  102. package/types/workflow.d.ts +50 -3
package/server/mcp.ts CHANGED
@@ -10,72 +10,18 @@ import {
10
10
  ErrorCode,
11
11
  } from "@modelcontextprotocol/sdk/types.js";
12
12
  import { StreamableHTTPTransport } from "@hono/mcp";
13
- import type Joi from "joi";
14
13
  import { cfg } from "./config";
15
14
  import { useRest } from "../database/rest";
15
+ import { createAgents } from "../lib/agents";
16
+ import { createApi } from "../lib/api";
16
17
  import { logger } from "../utils/logger";
17
18
  import type { McpTool, McpResource } from "../types/mcp";
18
19
  import type { HonoVariables } from "./env";
20
+ import { joiToJsonSchema } from "../lib/jsonSchema";
21
+ import { patterns } from "../lib/endpoints";
19
22
 
20
- // ─── Joi → JSON Schema (for the MCP protocol) ────────────────────────────
21
-
22
- function joiTypeToJson(type: string): string {
23
- switch (type) {
24
- case 'number': return 'number';
25
- case 'integer': return 'integer';
26
- case 'boolean': return 'boolean';
27
- case 'date': return 'string';
28
- default: return 'string';
29
- }
30
- }
31
-
32
- /** Minimal Joi → JSON Schema converter (covers the common field types). */
33
- function joiToJsonSchema(schema: Joi.Schema, describe = schema.describe() as any): any {
34
- const node: any = {};
35
- const type = describe?.type;
36
-
37
- switch (type) {
38
- case 'object': {
39
- node.type = 'object';
40
- const properties: Record<string, any> = {};
41
- const required: string[] = [];
42
- for (const [key, child] of Object.entries(describe.keys ?? {})) {
43
- properties[key] = joiToJsonSchema(child as any, child);
44
- if ((child as any)?.flags?.presence === 'required') required.push(key);
45
- }
46
- node.properties = properties;
47
- if (required.length) node.required = required;
48
- break;
49
- }
50
- case 'array': {
51
- node.type = 'array';
52
- if (describe.items?.length) node.items = joiToJsonSchema(describe.items[0], describe.items[0]);
53
- break;
54
- }
55
- default: {
56
- node.type = joiTypeToJson(type);
57
- if (type === 'date') node.format = 'date-time';
58
- if (type === 'string') {
59
- for (const rule of describe.rules ?? []) {
60
- if (['email', 'uri', 'uuid', 'isoDate', 'ip'].includes(rule.name)) {
61
- node.format = rule.name;
62
- }
63
- if (rule.name === 'pattern' && rule.args?.regex) {
64
- node.pattern = String(rule.args.regex).replace(/^\/|\/[gimsuy]*$/g, '');
65
- }
66
- }
67
- }
68
- if (describe.valids?.length && describe.valids.length <= 50) {
69
- node.enum = describe.valids;
70
- }
71
- break;
72
- }
73
- }
74
-
75
- if (describe?.flags?.presence === 'required') node.description = node.description ?? 'required';
76
- if (describe?.flags?.description) node.description = describe.flags.description;
77
- return node;
78
- }
23
+ // The Joi → JSON Schema converter is shared with the agent runtime — a tool
24
+ // must look identical whether it is exposed over MCP or to a model.
79
25
 
80
26
  // ─── URI template matching (users://{id} → params) ───────────────────────
81
27
 
@@ -148,7 +94,13 @@ function buildServer(tenantId: string, tools: McpTool[], resources: McpResource[
148
94
 
149
95
  const rest = new useRest({ tenant_id: tenantId });
150
96
  try {
151
- const result = await tool.exec({ c: undefined as any, rest, args: value });
97
+ const result = await tool.exec({
98
+ c: undefined as any,
99
+ rest,
100
+ args: value,
101
+ agents: createAgents(tenantId, rest),
102
+ api: createApi(rest),
103
+ });
152
104
  const isError = !!(result as any)?.isError;
153
105
  logger[isError ? 'warn' : 'info']('MCP tools/call', { method: 'tools/call', tenant: tenantId, tool: req.params.name, args: value, isError, duration: ms(start) });
154
106
  if (result && Array.isArray(result.content)) return result;
@@ -205,6 +157,8 @@ function buildServer(tenantId: string, tools: McpTool[], resources: McpResource[
205
157
  const result = await matched.resource.read({
206
158
  c: undefined as any,
207
159
  rest,
160
+ agents: createAgents(tenantId, rest),
161
+ api: createApi(rest),
208
162
  params: matched.params,
209
163
  uri,
210
164
  });
@@ -221,7 +175,7 @@ function buildServer(tenantId: string, tools: McpTool[], resources: McpResource[
221
175
 
222
176
  /**
223
177
  * Expose each tenant's MCP tools & resources over the Model Context Protocol
224
- * at `GET/POST /mcp/:tenant_id` (Streamable HTTP transport — works with
178
+ * at `GET/POST /api/:tenant_id/mcp` (Streamable HTTP transport — works with
225
179
  * Claude, Cursor, VS Code, and any MCP client).
226
180
  */
227
181
  export function initializeMcp(app: Hono<{ Variables: HonoVariables }>) {
@@ -238,7 +192,7 @@ export function initializeMcp(app: Hono<{ Variables: HonoVariables }>) {
238
192
  resourcesByTenant.set(resource._tenant_ ?? '', list);
239
193
  }
240
194
 
241
- app.all('/mcp/:tenant_id', async (c: Context<{ Variables: HonoVariables }>) => {
195
+ app.all(patterns.mcp, async (c: Context<{ Variables: HonoVariables }>) => {
242
196
  const tenantId = c.req.param('tenant_id') ?? '';
243
197
  const tools = toolsByTenant.get(tenantId) ?? [];
244
198
  const resources = resourcesByTenant.get(tenantId) ?? [];
package/server/routes.ts CHANGED
@@ -3,10 +3,26 @@ import { cfg } from "./config";
3
3
  import path from "path";
4
4
  import { jwt } from "../utils/func";
5
5
  import { useRest } from "../database/rest";
6
+ import { createAgents } from "../lib/agents";
7
+ import { createApi } from "../lib/api";
6
8
  import { io } from "./io";
7
9
  import { requestCtxStorage } from "../lib/asyncContextStorage";
8
10
  import type { HonoVariables } from "./env";
9
11
 
12
+ /** The context of a route handler — `rest` and `agents` share the same tenant. */
13
+ function routeContext(c: any, tenantId: string) {
14
+ const rest = new useRest({ tenant_id: tenantId });
15
+ return {
16
+ c,
17
+ rest,
18
+ // Tenant-scoped LLM registry, bound to this request's `rest`
19
+ agents: createAgents(tenantId, rest),
20
+ api: createApi(rest),
21
+ jwt: jwt,
22
+ io: io,
23
+ };
24
+ }
25
+
10
26
  function initializeRoutes(app: Hono<{ Variables: HonoVariables }>) {
11
27
  for (let route of cfg.routes ?? []) {
12
28
  if (route._prefix_) {
@@ -24,42 +40,21 @@ function initializeRoutes(app: Hono<{ Variables: HonoVariables }>) {
24
40
  if (route.method == "GET") {
25
41
  app.get(routePath, async (c) => { //
26
42
  resolveTenant();
27
- return route.handler({
28
- c,
29
- rest: new useRest({
30
- tenant_id: route._tenant_,
31
- }),
32
- jwt: jwt,
33
- io: io,
34
- });
43
+ return route.handler(routeContext(c, route._tenant_!));
35
44
  });
36
45
  }
37
46
 
38
47
  if (route.method == 'POST') {
39
48
  app.post(routePath, async (c) => {
40
49
  resolveTenant();
41
- return route.handler({
42
- c,
43
- rest: new useRest({
44
- tenant_id: route._tenant_,
45
- }),
46
- jwt: jwt,
47
- io: io,
48
- });
50
+ return route.handler(routeContext(c, route._tenant_!));
49
51
  });
50
52
  }
51
53
 
52
54
  if (route.method == "PUT") {
53
55
  app.put(routePath, async (c) => { //
54
56
  resolveTenant();
55
- return route.handler({
56
- c,
57
- rest: new useRest({
58
- tenant_id: route._tenant_,
59
- }),
60
- jwt: jwt,
61
- io: io,
62
- });
57
+ return route.handler(routeContext(c, route._tenant_!));
63
58
  });
64
59
  }
65
60
  }