4runr-os 2.10.2 → 2.10.3
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/apps/gateway/package-lock.json +18 -18
- package/package.json +3 -2
- package/prisma/migrations/20250806234307_add_agent_model/migration.sql +23 -0
- package/prisma/migrations/20250806234618_add_token_model/migration.sql +24 -0
- package/prisma/migrations/20250807002545_add_request_log_model/migration.sql +12 -0
- package/prisma/migrations/20250811200143_init/migration.sql +75 -0
- package/prisma/migrations/20250820014813_add_agent_runtime_models/migration.sql +44 -0
- package/prisma/migrations/20250820024550_task003_monitoring/migration.sql +49 -0
- package/prisma/migrations/20250820160424_task005_demo_tags/migration.sql +26 -0
- package/prisma/migrations/20250820162446_task006_trigger_tracking/migration.sql +24 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +469 -0
- package/scripts/postinstall-gateway.js +26 -1
|
@@ -261,9 +261,9 @@
|
|
|
261
261
|
}
|
|
262
262
|
},
|
|
263
263
|
"node_modules/@aws-sdk/client-kms": {
|
|
264
|
-
"version": "3.
|
|
265
|
-
"resolved": "https://registry.npmjs.org/@aws-sdk/client-kms/-/client-kms-3.
|
|
266
|
-
"integrity": "sha512-
|
|
264
|
+
"version": "3.1037.0",
|
|
265
|
+
"resolved": "https://registry.npmjs.org/@aws-sdk/client-kms/-/client-kms-3.1037.0.tgz",
|
|
266
|
+
"integrity": "sha512-kCaCPJVob3ArRGqBougLiHkarRKJx4C5okwX54VJVdSrsKmF/HMXsFXWB7DAS3mfvc5HGaTUstneuaM7VmhO6A==",
|
|
267
267
|
"license": "Apache-2.0",
|
|
268
268
|
"dependencies": {
|
|
269
269
|
"@aws-crypto/sha256-browser": "5.2.0",
|
|
@@ -311,9 +311,9 @@
|
|
|
311
311
|
}
|
|
312
312
|
},
|
|
313
313
|
"node_modules/@aws-sdk/client-secrets-manager": {
|
|
314
|
-
"version": "3.
|
|
315
|
-
"resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.
|
|
316
|
-
"integrity": "sha512-
|
|
314
|
+
"version": "3.1037.0",
|
|
315
|
+
"resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.1037.0.tgz",
|
|
316
|
+
"integrity": "sha512-SBXVNgXdzFeiuUod1AZXJexTDndPcpSTGOrVDe5Ny81Xq7d3r18th7ZTzvnc7BsD9MQa8SckNgOYscvi/fYZhw==",
|
|
317
317
|
"license": "Apache-2.0",
|
|
318
318
|
"dependencies": {
|
|
319
319
|
"@aws-crypto/sha256-browser": "5.2.0",
|
|
@@ -361,9 +361,9 @@
|
|
|
361
361
|
}
|
|
362
362
|
},
|
|
363
363
|
"node_modules/@aws-sdk/client-ssm": {
|
|
364
|
-
"version": "3.
|
|
365
|
-
"resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.
|
|
366
|
-
"integrity": "sha512-
|
|
364
|
+
"version": "3.1037.0",
|
|
365
|
+
"resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.1037.0.tgz",
|
|
366
|
+
"integrity": "sha512-bpOon1QQ+FN1yH7NbjjHnyQ7y5xPvS/3vS2nL3+e2+Iu9sA+WJwgwquk6N+U1EtnAuGPAl9eNzk0GnEHaIwAOQ==",
|
|
367
367
|
"license": "Apache-2.0",
|
|
368
368
|
"dependencies": {
|
|
369
369
|
"@aws-crypto/sha256-browser": "5.2.0",
|
|
@@ -1964,9 +1964,9 @@
|
|
|
1964
1964
|
}
|
|
1965
1965
|
},
|
|
1966
1966
|
"node_modules/@fastify/ajv-compiler/node_modules/ajv": {
|
|
1967
|
-
"version": "8.
|
|
1968
|
-
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.
|
|
1969
|
-
"integrity": "sha512-
|
|
1967
|
+
"version": "8.20.0",
|
|
1968
|
+
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
|
|
1969
|
+
"integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
|
|
1970
1970
|
"license": "MIT",
|
|
1971
1971
|
"dependencies": {
|
|
1972
1972
|
"fast-deep-equal": "^3.1.3",
|
|
@@ -4102,9 +4102,9 @@
|
|
|
4102
4102
|
}
|
|
4103
4103
|
},
|
|
4104
4104
|
"node_modules/ajv-formats/node_modules/ajv": {
|
|
4105
|
-
"version": "8.
|
|
4106
|
-
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.
|
|
4107
|
-
"integrity": "sha512-
|
|
4105
|
+
"version": "8.20.0",
|
|
4106
|
+
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
|
|
4107
|
+
"integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
|
|
4108
4108
|
"license": "MIT",
|
|
4109
4109
|
"dependencies": {
|
|
4110
4110
|
"fast-deep-equal": "^3.1.3",
|
|
@@ -5420,9 +5420,9 @@
|
|
|
5420
5420
|
}
|
|
5421
5421
|
},
|
|
5422
5422
|
"node_modules/fast-json-stringify/node_modules/ajv": {
|
|
5423
|
-
"version": "8.
|
|
5424
|
-
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.
|
|
5425
|
-
"integrity": "sha512-
|
|
5423
|
+
"version": "8.20.0",
|
|
5424
|
+
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
|
|
5425
|
+
"integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
|
|
5426
5426
|
"license": "MIT",
|
|
5427
5427
|
"dependencies": {
|
|
5428
5428
|
"fast-deep-equal": "^3.1.3",
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "4runr-os",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.3",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.10.
|
|
5
|
+
"description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.10.3: npm global Gateway — ship prisma/ in package, postinstall always runs prisma generate (fixes @prisma/client not initialized). v2.10.2: Portal monitoring metrics. v2.10.1+ Docker Postgres+Redis in auto mode. See docs/4RUNR-DB-IMPLEMENTATION-PLAN.md, docs/MONITORING-IMPROVEMENTS-V1.md",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"4runr": "dist/index.js",
|
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
"mk3-tui/bin/**/*",
|
|
85
85
|
"mk3-tui/binaries/**/*",
|
|
86
86
|
"apps/gateway/**/*",
|
|
87
|
+
"prisma/**/*",
|
|
87
88
|
"packages/shared/package.json",
|
|
88
89
|
"packages/shared/dist/**/*",
|
|
89
90
|
"packages/sentinel/package.json",
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "Agent" (
|
|
3
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
4
|
+
"name" TEXT NOT NULL,
|
|
5
|
+
"role" TEXT NOT NULL,
|
|
6
|
+
"createdBy" TEXT NOT NULL,
|
|
7
|
+
"publicKey" TEXT NOT NULL,
|
|
8
|
+
"status" TEXT NOT NULL DEFAULT 'active',
|
|
9
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
-- CreateTable
|
|
13
|
+
CREATE TABLE "Token" (
|
|
14
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
15
|
+
"agentId" TEXT NOT NULL,
|
|
16
|
+
"token" TEXT NOT NULL,
|
|
17
|
+
"expiresAt" DATETIME NOT NULL,
|
|
18
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
19
|
+
CONSTRAINT "Token_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "Agent" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
-- CreateIndex
|
|
23
|
+
CREATE UNIQUE INDEX "Token_token_key" ON "Token"("token");
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Warnings:
|
|
3
|
+
|
|
4
|
+
- You are about to drop the column `token` on the `Token` table. All the data in the column will be lost.
|
|
5
|
+
- Added the required column `encrypted` to the `Token` table without a default value. This is not possible if the table is not empty.
|
|
6
|
+
|
|
7
|
+
*/
|
|
8
|
+
-- RedefineTables
|
|
9
|
+
PRAGMA defer_foreign_keys=ON;
|
|
10
|
+
PRAGMA foreign_keys=OFF;
|
|
11
|
+
CREATE TABLE "new_Token" (
|
|
12
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
13
|
+
"agentId" TEXT NOT NULL,
|
|
14
|
+
"encrypted" TEXT NOT NULL,
|
|
15
|
+
"expiresAt" DATETIME NOT NULL,
|
|
16
|
+
"revoked" BOOLEAN NOT NULL DEFAULT false,
|
|
17
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
18
|
+
CONSTRAINT "Token_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "Agent" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
19
|
+
);
|
|
20
|
+
INSERT INTO "new_Token" ("agentId", "createdAt", "expiresAt", "id") SELECT "agentId", "createdAt", "expiresAt", "id" FROM "Token";
|
|
21
|
+
DROP TABLE "Token";
|
|
22
|
+
ALTER TABLE "new_Token" RENAME TO "Token";
|
|
23
|
+
PRAGMA foreign_keys=ON;
|
|
24
|
+
PRAGMA defer_foreign_keys=OFF;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "RequestLog" (
|
|
3
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
4
|
+
"agentId" TEXT NOT NULL,
|
|
5
|
+
"tool" TEXT NOT NULL,
|
|
6
|
+
"action" TEXT NOT NULL,
|
|
7
|
+
"responseTime" INTEGER NOT NULL,
|
|
8
|
+
"statusCode" INTEGER NOT NULL,
|
|
9
|
+
"success" BOOLEAN NOT NULL,
|
|
10
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
11
|
+
CONSTRAINT "RequestLog_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "Agent" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
12
|
+
);
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "Policy" (
|
|
3
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
4
|
+
"name" TEXT NOT NULL,
|
|
5
|
+
"description" TEXT,
|
|
6
|
+
"agentId" TEXT,
|
|
7
|
+
"role" TEXT,
|
|
8
|
+
"spec" TEXT NOT NULL,
|
|
9
|
+
"specHash" TEXT NOT NULL,
|
|
10
|
+
"active" BOOLEAN NOT NULL DEFAULT true,
|
|
11
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
12
|
+
"updatedAt" DATETIME NOT NULL,
|
|
13
|
+
CONSTRAINT "Policy_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "Agent" ("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
-- CreateTable
|
|
17
|
+
CREATE TABLE "PolicyLog" (
|
|
18
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
19
|
+
"policyId" TEXT NOT NULL,
|
|
20
|
+
"agentId" TEXT NOT NULL,
|
|
21
|
+
"tool" TEXT NOT NULL,
|
|
22
|
+
"action" TEXT NOT NULL,
|
|
23
|
+
"decision" TEXT NOT NULL,
|
|
24
|
+
"reason" TEXT,
|
|
25
|
+
"requestData" TEXT,
|
|
26
|
+
"responseData" TEXT,
|
|
27
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
28
|
+
CONSTRAINT "PolicyLog_policyId_fkey" FOREIGN KEY ("policyId") REFERENCES "Policy" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
|
29
|
+
CONSTRAINT "PolicyLog_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "Agent" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
-- CreateTable
|
|
33
|
+
CREATE TABLE "QuotaCounter" (
|
|
34
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
35
|
+
"policyId" TEXT NOT NULL,
|
|
36
|
+
"quotaKey" TEXT NOT NULL,
|
|
37
|
+
"current" INTEGER NOT NULL DEFAULT 0,
|
|
38
|
+
"resetAt" DATETIME NOT NULL,
|
|
39
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
40
|
+
"updatedAt" DATETIME NOT NULL,
|
|
41
|
+
CONSTRAINT "QuotaCounter_policyId_fkey" FOREIGN KEY ("policyId") REFERENCES "Policy" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
-- CreateTable
|
|
45
|
+
CREATE TABLE "ToolCredential" (
|
|
46
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
47
|
+
"tool" TEXT NOT NULL,
|
|
48
|
+
"version" TEXT NOT NULL,
|
|
49
|
+
"isActive" BOOLEAN NOT NULL DEFAULT false,
|
|
50
|
+
"encryptedCredential" TEXT NOT NULL,
|
|
51
|
+
"metadata" TEXT,
|
|
52
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
53
|
+
"updatedAt" DATETIME NOT NULL,
|
|
54
|
+
"activatedAt" DATETIME,
|
|
55
|
+
"deactivatedAt" DATETIME
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
-- CreateTable
|
|
59
|
+
CREATE TABLE "TokenRegistry" (
|
|
60
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
61
|
+
"tokenId" TEXT NOT NULL,
|
|
62
|
+
"agentId" TEXT NOT NULL,
|
|
63
|
+
"payloadHash" TEXT NOT NULL,
|
|
64
|
+
"issuedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
65
|
+
"expiresAt" DATETIME NOT NULL,
|
|
66
|
+
"isRevoked" BOOLEAN NOT NULL DEFAULT false,
|
|
67
|
+
"revokedAt" DATETIME,
|
|
68
|
+
CONSTRAINT "TokenRegistry_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "Agent" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
-- CreateIndex
|
|
72
|
+
CREATE UNIQUE INDEX "ToolCredential_tool_version_key" ON "ToolCredential"("tool", "version");
|
|
73
|
+
|
|
74
|
+
-- CreateIndex
|
|
75
|
+
CREATE UNIQUE INDEX "TokenRegistry_tokenId_key" ON "TokenRegistry"("tokenId");
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "runtime_agents" (
|
|
3
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
4
|
+
"name" TEXT NOT NULL,
|
|
5
|
+
"language" TEXT NOT NULL,
|
|
6
|
+
"sourceType" TEXT NOT NULL DEFAULT 'ZIP',
|
|
7
|
+
"sourceUri" TEXT,
|
|
8
|
+
"entrypoint" TEXT NOT NULL,
|
|
9
|
+
"env" JSONB NOT NULL,
|
|
10
|
+
"limitsCpu" REAL,
|
|
11
|
+
"limitsMemMb" INTEGER,
|
|
12
|
+
"networkMode" TEXT NOT NULL DEFAULT 'NONE',
|
|
13
|
+
"status" TEXT NOT NULL DEFAULT 'READY',
|
|
14
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
15
|
+
"updatedAt" DATETIME NOT NULL
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
-- CreateTable
|
|
19
|
+
CREATE TABLE "runtime_runs" (
|
|
20
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
21
|
+
"agentId" TEXT NOT NULL,
|
|
22
|
+
"status" TEXT NOT NULL DEFAULT 'QUEUED',
|
|
23
|
+
"startedAt" DATETIME,
|
|
24
|
+
"endedAt" DATETIME,
|
|
25
|
+
"exitCode" INTEGER,
|
|
26
|
+
"reason" TEXT,
|
|
27
|
+
"cpuSeconds" REAL,
|
|
28
|
+
"maxMemMb" INTEGER,
|
|
29
|
+
"logsPtr" TEXT,
|
|
30
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
31
|
+
CONSTRAINT "runtime_runs_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "runtime_agents" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
-- CreateTable
|
|
35
|
+
CREATE TABLE "runtime_schedules" (
|
|
36
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
37
|
+
"agentId" TEXT NOT NULL,
|
|
38
|
+
"cronExpr" TEXT NOT NULL,
|
|
39
|
+
"enabled" BOOLEAN NOT NULL DEFAULT true,
|
|
40
|
+
"lastRunAt" DATETIME,
|
|
41
|
+
"nextRunAt" DATETIME,
|
|
42
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
43
|
+
CONSTRAINT "runtime_schedules_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "runtime_agents" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
|
44
|
+
);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Warnings:
|
|
3
|
+
|
|
4
|
+
- You are about to drop the column `logsPtr` on the `runtime_runs` table. All the data in the column will be lost.
|
|
5
|
+
|
|
6
|
+
*/
|
|
7
|
+
-- RedefineTables
|
|
8
|
+
PRAGMA defer_foreign_keys=ON;
|
|
9
|
+
PRAGMA foreign_keys=OFF;
|
|
10
|
+
CREATE TABLE "new_runtime_agents" (
|
|
11
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
12
|
+
"name" TEXT NOT NULL,
|
|
13
|
+
"language" TEXT NOT NULL,
|
|
14
|
+
"sourceType" TEXT NOT NULL DEFAULT 'ZIP',
|
|
15
|
+
"sourceUri" TEXT,
|
|
16
|
+
"entrypoint" TEXT NOT NULL,
|
|
17
|
+
"env" JSONB NOT NULL,
|
|
18
|
+
"limitsCpu" REAL,
|
|
19
|
+
"limitsMemMb" INTEGER,
|
|
20
|
+
"networkMode" TEXT NOT NULL DEFAULT 'NONE',
|
|
21
|
+
"status" TEXT NOT NULL DEFAULT 'READY',
|
|
22
|
+
"maxRestarts" INTEGER NOT NULL DEFAULT 2,
|
|
23
|
+
"restartBackoffMs" INTEGER NOT NULL DEFAULT 5000,
|
|
24
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
25
|
+
"updatedAt" DATETIME NOT NULL
|
|
26
|
+
);
|
|
27
|
+
INSERT INTO "new_runtime_agents" ("createdAt", "entrypoint", "env", "id", "language", "limitsCpu", "limitsMemMb", "name", "networkMode", "sourceType", "sourceUri", "status", "updatedAt") SELECT "createdAt", "entrypoint", "env", "id", "language", "limitsCpu", "limitsMemMb", "name", "networkMode", "sourceType", "sourceUri", "status", "updatedAt" FROM "runtime_agents";
|
|
28
|
+
DROP TABLE "runtime_agents";
|
|
29
|
+
ALTER TABLE "new_runtime_agents" RENAME TO "runtime_agents";
|
|
30
|
+
CREATE TABLE "new_runtime_runs" (
|
|
31
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
32
|
+
"agentId" TEXT NOT NULL,
|
|
33
|
+
"status" TEXT NOT NULL DEFAULT 'QUEUED',
|
|
34
|
+
"startedAt" DATETIME,
|
|
35
|
+
"endedAt" DATETIME,
|
|
36
|
+
"exitCode" INTEGER,
|
|
37
|
+
"reason" TEXT,
|
|
38
|
+
"cpuSeconds" REAL,
|
|
39
|
+
"maxMemMb" INTEGER,
|
|
40
|
+
"restarts" INTEGER NOT NULL DEFAULT 0,
|
|
41
|
+
"lastSampleAt" DATETIME,
|
|
42
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
43
|
+
CONSTRAINT "runtime_runs_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "runtime_agents" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
|
44
|
+
);
|
|
45
|
+
INSERT INTO "new_runtime_runs" ("agentId", "cpuSeconds", "createdAt", "endedAt", "exitCode", "id", "maxMemMb", "reason", "startedAt", "status") SELECT "agentId", "cpuSeconds", "createdAt", "endedAt", "exitCode", "id", "maxMemMb", "reason", "startedAt", "status" FROM "runtime_runs";
|
|
46
|
+
DROP TABLE "runtime_runs";
|
|
47
|
+
ALTER TABLE "new_runtime_runs" RENAME TO "runtime_runs";
|
|
48
|
+
PRAGMA foreign_keys=ON;
|
|
49
|
+
PRAGMA defer_foreign_keys=OFF;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
-- RedefineTables
|
|
2
|
+
PRAGMA defer_foreign_keys=ON;
|
|
3
|
+
PRAGMA foreign_keys=OFF;
|
|
4
|
+
CREATE TABLE "new_runtime_agents" (
|
|
5
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
6
|
+
"name" TEXT NOT NULL,
|
|
7
|
+
"language" TEXT NOT NULL,
|
|
8
|
+
"sourceType" TEXT NOT NULL DEFAULT 'ZIP',
|
|
9
|
+
"sourceUri" TEXT,
|
|
10
|
+
"entrypoint" TEXT NOT NULL,
|
|
11
|
+
"env" JSONB NOT NULL,
|
|
12
|
+
"limitsCpu" REAL,
|
|
13
|
+
"limitsMemMb" INTEGER,
|
|
14
|
+
"networkMode" TEXT NOT NULL DEFAULT 'NONE',
|
|
15
|
+
"status" TEXT NOT NULL DEFAULT 'READY',
|
|
16
|
+
"maxRestarts" INTEGER NOT NULL DEFAULT 2,
|
|
17
|
+
"restartBackoffMs" INTEGER NOT NULL DEFAULT 5000,
|
|
18
|
+
"tags" JSONB NOT NULL DEFAULT [],
|
|
19
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
20
|
+
"updatedAt" DATETIME NOT NULL
|
|
21
|
+
);
|
|
22
|
+
INSERT INTO "new_runtime_agents" ("createdAt", "entrypoint", "env", "id", "language", "limitsCpu", "limitsMemMb", "maxRestarts", "name", "networkMode", "restartBackoffMs", "sourceType", "sourceUri", "status", "updatedAt") SELECT "createdAt", "entrypoint", "env", "id", "language", "limitsCpu", "limitsMemMb", "maxRestarts", "name", "networkMode", "restartBackoffMs", "sourceType", "sourceUri", "status", "updatedAt" FROM "runtime_agents";
|
|
23
|
+
DROP TABLE "runtime_agents";
|
|
24
|
+
ALTER TABLE "new_runtime_agents" RENAME TO "runtime_agents";
|
|
25
|
+
PRAGMA foreign_keys=ON;
|
|
26
|
+
PRAGMA defer_foreign_keys=OFF;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
-- RedefineTables
|
|
2
|
+
PRAGMA defer_foreign_keys=ON;
|
|
3
|
+
PRAGMA foreign_keys=OFF;
|
|
4
|
+
CREATE TABLE "new_runtime_runs" (
|
|
5
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
6
|
+
"agentId" TEXT NOT NULL,
|
|
7
|
+
"status" TEXT NOT NULL DEFAULT 'QUEUED',
|
|
8
|
+
"startedAt" DATETIME,
|
|
9
|
+
"endedAt" DATETIME,
|
|
10
|
+
"exitCode" INTEGER,
|
|
11
|
+
"reason" TEXT,
|
|
12
|
+
"cpuSeconds" REAL,
|
|
13
|
+
"maxMemMb" INTEGER,
|
|
14
|
+
"restarts" INTEGER NOT NULL DEFAULT 0,
|
|
15
|
+
"lastSampleAt" DATETIME,
|
|
16
|
+
"triggeredBy" TEXT NOT NULL DEFAULT 'MANUAL',
|
|
17
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
18
|
+
CONSTRAINT "runtime_runs_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "runtime_agents" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
|
19
|
+
);
|
|
20
|
+
INSERT INTO "new_runtime_runs" ("agentId", "cpuSeconds", "createdAt", "endedAt", "exitCode", "id", "lastSampleAt", "maxMemMb", "reason", "restarts", "startedAt", "status") SELECT "agentId", "cpuSeconds", "createdAt", "endedAt", "exitCode", "id", "lastSampleAt", "maxMemMb", "reason", "restarts", "startedAt", "status" FROM "runtime_runs";
|
|
21
|
+
DROP TABLE "runtime_runs";
|
|
22
|
+
ALTER TABLE "new_runtime_runs" RENAME TO "runtime_runs";
|
|
23
|
+
PRAGMA foreign_keys=ON;
|
|
24
|
+
PRAGMA defer_foreign_keys=OFF;
|
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
// This is your Prisma schema file,
|
|
2
|
+
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
|
3
|
+
|
|
4
|
+
generator client {
|
|
5
|
+
provider = "prisma-client-js"
|
|
6
|
+
binaryTargets = ["native", "linux-musl-openssl-3.0.x", "linux-musl"]
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
datasource db {
|
|
10
|
+
provider = "postgresql"
|
|
11
|
+
url = env("DATABASE_URL")
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
model Agent {
|
|
15
|
+
id String @id @default(uuid())
|
|
16
|
+
name String
|
|
17
|
+
role String
|
|
18
|
+
createdBy String
|
|
19
|
+
publicKey String
|
|
20
|
+
status String @default("active")
|
|
21
|
+
createdAt DateTime @default(now())
|
|
22
|
+
tokens Token[]
|
|
23
|
+
requestLogs RequestLog[]
|
|
24
|
+
policies Policy[]
|
|
25
|
+
policyLogs PolicyLog[]
|
|
26
|
+
tokenRegistries TokenRegistry[]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
model Token {
|
|
30
|
+
id String @id @default(uuid())
|
|
31
|
+
agentId String
|
|
32
|
+
agent Agent @relation(fields: [agentId], references: [id])
|
|
33
|
+
encrypted String
|
|
34
|
+
expiresAt DateTime
|
|
35
|
+
revoked Boolean @default(false)
|
|
36
|
+
createdAt DateTime @default(now())
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
model RequestLog {
|
|
40
|
+
id String @id @default(uuid())
|
|
41
|
+
agentId String
|
|
42
|
+
agent Agent @relation(fields: [agentId], references: [id])
|
|
43
|
+
tool String
|
|
44
|
+
action String
|
|
45
|
+
responseTime Int // milliseconds
|
|
46
|
+
statusCode Int
|
|
47
|
+
success Boolean
|
|
48
|
+
createdAt DateTime @default(now())
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
model Policy {
|
|
52
|
+
id String @id @default(uuid())
|
|
53
|
+
name String
|
|
54
|
+
description String?
|
|
55
|
+
agentId String? // null for role-based policies
|
|
56
|
+
role String? // null for agent-specific policies
|
|
57
|
+
spec String // JSON policy specification
|
|
58
|
+
specHash String // SHA256 hash of spec for change detection
|
|
59
|
+
active Boolean @default(true)
|
|
60
|
+
createdAt DateTime @default(now())
|
|
61
|
+
updatedAt DateTime @updatedAt
|
|
62
|
+
agent Agent? @relation(fields: [agentId], references: [id])
|
|
63
|
+
policyLogs PolicyLog[]
|
|
64
|
+
quotaCounters QuotaCounter[]
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
model PolicyLog {
|
|
68
|
+
id String @id @default(uuid())
|
|
69
|
+
policyId String
|
|
70
|
+
agentId String
|
|
71
|
+
tool String
|
|
72
|
+
action String
|
|
73
|
+
decision String // "allow", "deny"
|
|
74
|
+
reason String? // denial reason
|
|
75
|
+
requestData String? // JSON request data (truncated)
|
|
76
|
+
responseData String? // JSON response data (truncated)
|
|
77
|
+
createdAt DateTime @default(now())
|
|
78
|
+
policy Policy @relation(fields: [policyId], references: [id])
|
|
79
|
+
agent Agent @relation(fields: [agentId], references: [id])
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
model QuotaCounter {
|
|
83
|
+
id String @id @default(uuid())
|
|
84
|
+
policyId String
|
|
85
|
+
quotaKey String // e.g., "serpapi:search:2024-01-15"
|
|
86
|
+
current Int @default(0)
|
|
87
|
+
resetAt DateTime
|
|
88
|
+
createdAt DateTime @default(now())
|
|
89
|
+
updatedAt DateTime @updatedAt
|
|
90
|
+
policy Policy @relation(fields: [policyId], references: [id])
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
model ToolCredential {
|
|
94
|
+
id String @id @default(uuid())
|
|
95
|
+
tool String // e.g., "serpapi", "openai", "gmail_send"
|
|
96
|
+
version String // e.g., "v1", "v2"
|
|
97
|
+
isActive Boolean @default(false)
|
|
98
|
+
encryptedCredential String // Encrypted credential data
|
|
99
|
+
metadata String? // JSON metadata (encrypted)
|
|
100
|
+
createdAt DateTime @default(now())
|
|
101
|
+
updatedAt DateTime @updatedAt
|
|
102
|
+
activatedAt DateTime?
|
|
103
|
+
deactivatedAt DateTime?
|
|
104
|
+
|
|
105
|
+
@@unique([tool, version])
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
model TokenRegistry {
|
|
109
|
+
id String @id @default(uuid())
|
|
110
|
+
tokenId String @unique // The token ID issued to the agent
|
|
111
|
+
agentId String
|
|
112
|
+
payloadHash String // SHA256 hash of the token payload
|
|
113
|
+
issuedAt DateTime @default(now())
|
|
114
|
+
expiresAt DateTime
|
|
115
|
+
isRevoked Boolean @default(false)
|
|
116
|
+
revokedAt DateTime?
|
|
117
|
+
agent Agent @relation(fields: [agentId], references: [id])
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ====== AI AGENT RUNTIME MODELS (TASK-001) ======
|
|
121
|
+
|
|
122
|
+
model RuntimeAgent {
|
|
123
|
+
id String @id @default(uuid())
|
|
124
|
+
name String
|
|
125
|
+
language AgentLanguage
|
|
126
|
+
sourceType SourceType @default(ZIP) // ZIP | GIT (ZIP for MVP)
|
|
127
|
+
sourceUri String? // path to extracted zip in local FS (MVP)
|
|
128
|
+
entrypoint String // index.js | main.py
|
|
129
|
+
env Json // non-secret env vars (secrets via Gateway only)
|
|
130
|
+
limitsCpu Float? // e.g. 0.5
|
|
131
|
+
limitsMemMb Int? // e.g. 256
|
|
132
|
+
networkMode NetworkMode @default(NONE) // NONE | EGRESS (via Gateway proxy only)
|
|
133
|
+
status AgentStatus @default(READY)
|
|
134
|
+
// NEW: restart policy & limits
|
|
135
|
+
maxRestarts Int @default(2) // per run
|
|
136
|
+
restartBackoffMs Int @default(5000)
|
|
137
|
+
// NEW: tags for demo functionality (JSON array for SQLite compatibility)
|
|
138
|
+
tags Json @default("[]")
|
|
139
|
+
createdAt DateTime @default(now())
|
|
140
|
+
updatedAt DateTime @updatedAt
|
|
141
|
+
|
|
142
|
+
runs RuntimeRun[]
|
|
143
|
+
schedules RuntimeSchedule[]
|
|
144
|
+
|
|
145
|
+
@@map("runtime_agents")
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
model RuntimeRun {
|
|
149
|
+
id String @id @default(uuid())
|
|
150
|
+
agentId String
|
|
151
|
+
agent RuntimeAgent @relation(fields: [agentId], references: [id], onDelete: Cascade)
|
|
152
|
+
status RunStatus @default(QUEUED) // QUEUED | RUNNING | SUCCEEDED | FAILED | KILLED
|
|
153
|
+
startedAt DateTime?
|
|
154
|
+
endedAt DateTime?
|
|
155
|
+
exitCode Int?
|
|
156
|
+
reason String? // containerId or failure reason
|
|
157
|
+
// NEW: restart policy & limits
|
|
158
|
+
cpuSeconds Float? // cumulative seconds
|
|
159
|
+
maxMemMb Int? // peak RSS MB
|
|
160
|
+
restarts Int @default(0)
|
|
161
|
+
lastSampleAt DateTime? // last stats collection time
|
|
162
|
+
// NEW: trigger tracking
|
|
163
|
+
triggeredBy TriggerType @default(MANUAL)
|
|
164
|
+
// (optional) logsPtr for future
|
|
165
|
+
createdAt DateTime @default(now())
|
|
166
|
+
|
|
167
|
+
@@map("runtime_runs")
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
model RuntimeSchedule {
|
|
171
|
+
id String @id @default(uuid())
|
|
172
|
+
agentId String
|
|
173
|
+
agent RuntimeAgent @relation(fields: [agentId], references: [id], onDelete: Cascade)
|
|
174
|
+
cronExpr String
|
|
175
|
+
enabled Boolean @default(true)
|
|
176
|
+
lastRunAt DateTime?
|
|
177
|
+
nextRunAt DateTime?
|
|
178
|
+
createdAt DateTime @default(now())
|
|
179
|
+
|
|
180
|
+
@@map("runtime_schedules")
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
enum AgentLanguage {
|
|
184
|
+
NODE
|
|
185
|
+
PYTHON
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
enum SourceType {
|
|
189
|
+
ZIP
|
|
190
|
+
GIT
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
enum NetworkMode {
|
|
194
|
+
NONE
|
|
195
|
+
EGRESS
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
enum AgentStatus {
|
|
199
|
+
READY
|
|
200
|
+
ERROR
|
|
201
|
+
DISABLED
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
enum RunStatus {
|
|
205
|
+
CREATED
|
|
206
|
+
QUEUED
|
|
207
|
+
RUNNING
|
|
208
|
+
COMPLETED
|
|
209
|
+
FAILED
|
|
210
|
+
KILLED
|
|
211
|
+
SUCCEEDED // Alias for COMPLETED (keeping for RuntimeRun compatibility)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
enum TriggerType {
|
|
215
|
+
MANUAL
|
|
216
|
+
SCHEDULE
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// ====== GATEWAY RUNS MODELS ======
|
|
220
|
+
|
|
221
|
+
model Run {
|
|
222
|
+
id String @id @default(uuid())
|
|
223
|
+
name String
|
|
224
|
+
status RunStatus @default(CREATED)
|
|
225
|
+
input Json? // JSON input payload
|
|
226
|
+
output Json? // JSON output payload
|
|
227
|
+
logs Json @default("[]") // Array of log entries
|
|
228
|
+
clientToken String? @unique // Idempotency token from client
|
|
229
|
+
tags String[] @default([])
|
|
230
|
+
startedAt DateTime?
|
|
231
|
+
completedAt DateTime?
|
|
232
|
+
createdAt DateTime @default(now())
|
|
233
|
+
updatedAt DateTime @updatedAt
|
|
234
|
+
|
|
235
|
+
@@map("runs")
|
|
236
|
+
@@index([status])
|
|
237
|
+
@@index([clientToken])
|
|
238
|
+
@@index([createdAt])
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
model ApiKey {
|
|
242
|
+
id String @id @default(cuid())
|
|
243
|
+
key String @unique // Hashed or opaque token
|
|
244
|
+
label String?
|
|
245
|
+
revoked Boolean @default(false)
|
|
246
|
+
userId String? // Link to user if applicable
|
|
247
|
+
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
248
|
+
createdAt DateTime @default(now())
|
|
249
|
+
revokedAt DateTime?
|
|
250
|
+
|
|
251
|
+
@@map("api_keys")
|
|
252
|
+
@@index([key])
|
|
253
|
+
@@index([userId])
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ====== RBAC MODELS ======
|
|
257
|
+
|
|
258
|
+
model User {
|
|
259
|
+
id String @id @default(uuid())
|
|
260
|
+
email String @unique
|
|
261
|
+
username String @unique
|
|
262
|
+
passwordHash String? // Optional - can use external auth
|
|
263
|
+
status UserStatus @default(ACTIVE)
|
|
264
|
+
createdAt DateTime @default(now())
|
|
265
|
+
updatedAt DateTime @updatedAt
|
|
266
|
+
lastLoginAt DateTime?
|
|
267
|
+
|
|
268
|
+
// MFA fields
|
|
269
|
+
mfaEnabled Boolean @default(false)
|
|
270
|
+
mfaSecret String? // TOTP secret (encrypted)
|
|
271
|
+
mfaBackupCodes String[] @default([]) // Encrypted backup codes
|
|
272
|
+
mfaVerifiedAt DateTime? // When MFA was last verified
|
|
273
|
+
|
|
274
|
+
// Relations
|
|
275
|
+
roles UserRole[]
|
|
276
|
+
apiKeys ApiKey[]
|
|
277
|
+
sessions UserSession[]
|
|
278
|
+
|
|
279
|
+
@@map("users")
|
|
280
|
+
@@index([email])
|
|
281
|
+
@@index([username])
|
|
282
|
+
@@index([status])
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
model Role {
|
|
286
|
+
id String @id @default(uuid())
|
|
287
|
+
name String @unique
|
|
288
|
+
description String?
|
|
289
|
+
isSystem Boolean @default(false) // System roles cannot be deleted
|
|
290
|
+
createdAt DateTime @default(now())
|
|
291
|
+
updatedAt DateTime @updatedAt
|
|
292
|
+
|
|
293
|
+
// Relations
|
|
294
|
+
users UserRole[]
|
|
295
|
+
permissions RolePermission[]
|
|
296
|
+
|
|
297
|
+
@@map("roles")
|
|
298
|
+
@@index([name])
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
model Permission {
|
|
302
|
+
id String @id @default(uuid())
|
|
303
|
+
resource String // e.g., "runs", "agents", "users"
|
|
304
|
+
action String // e.g., "create", "read", "update", "delete", "execute"
|
|
305
|
+
description String?
|
|
306
|
+
createdAt DateTime @default(now())
|
|
307
|
+
|
|
308
|
+
// Relations
|
|
309
|
+
roles RolePermission[]
|
|
310
|
+
|
|
311
|
+
@@unique([resource, action])
|
|
312
|
+
@@map("permissions")
|
|
313
|
+
@@index([resource])
|
|
314
|
+
@@index([action])
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
model UserRole {
|
|
318
|
+
id String @id @default(uuid())
|
|
319
|
+
userId String
|
|
320
|
+
roleId String
|
|
321
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
322
|
+
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
|
323
|
+
assignedAt DateTime @default(now())
|
|
324
|
+
assignedBy String? // User ID who assigned this role
|
|
325
|
+
|
|
326
|
+
@@unique([userId, roleId])
|
|
327
|
+
@@map("user_roles")
|
|
328
|
+
@@index([userId])
|
|
329
|
+
@@index([roleId])
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
model RolePermission {
|
|
333
|
+
id String @id @default(uuid())
|
|
334
|
+
roleId String
|
|
335
|
+
permissionId String
|
|
336
|
+
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
|
337
|
+
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
|
|
338
|
+
grantedAt DateTime @default(now())
|
|
339
|
+
grantedBy String? // User ID who granted this permission
|
|
340
|
+
|
|
341
|
+
@@unique([roleId, permissionId])
|
|
342
|
+
@@map("role_permissions")
|
|
343
|
+
@@index([roleId])
|
|
344
|
+
@@index([permissionId])
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
model UserSession {
|
|
348
|
+
id String @id @default(uuid())
|
|
349
|
+
userId String
|
|
350
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
351
|
+
token String @unique // JWT or session token
|
|
352
|
+
ipAddress String?
|
|
353
|
+
userAgent String?
|
|
354
|
+
expiresAt DateTime
|
|
355
|
+
createdAt DateTime @default(now())
|
|
356
|
+
lastActivityAt DateTime @default(now())
|
|
357
|
+
|
|
358
|
+
@@map("user_sessions")
|
|
359
|
+
@@index([userId])
|
|
360
|
+
@@index([token])
|
|
361
|
+
@@index([expiresAt])
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
enum UserStatus {
|
|
365
|
+
ACTIVE
|
|
366
|
+
INACTIVE
|
|
367
|
+
SUSPENDED
|
|
368
|
+
DELETED
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// ====== IDEMPOTENCY & CACHE MODELS ======
|
|
372
|
+
|
|
373
|
+
model IdempotencyToken {
|
|
374
|
+
id String @id @default(uuid())
|
|
375
|
+
token String @unique
|
|
376
|
+
runId String? // Reference to Run if applicable
|
|
377
|
+
response Json? // Cached response
|
|
378
|
+
expiresAt DateTime
|
|
379
|
+
createdAt DateTime @default(now())
|
|
380
|
+
|
|
381
|
+
@@map("idempotency_tokens")
|
|
382
|
+
@@index([token])
|
|
383
|
+
@@index([expiresAt])
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
model CacheEntry {
|
|
387
|
+
id String @id @default(uuid())
|
|
388
|
+
key String @unique
|
|
389
|
+
value Json
|
|
390
|
+
expiresAt DateTime?
|
|
391
|
+
createdAt DateTime @default(now())
|
|
392
|
+
updatedAt DateTime @updatedAt
|
|
393
|
+
|
|
394
|
+
@@map("cache_entries")
|
|
395
|
+
@@index([key])
|
|
396
|
+
@@index([expiresAt])
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// ====== CHAT HISTORY MODELS ======
|
|
400
|
+
|
|
401
|
+
model ChatHistory {
|
|
402
|
+
id String @id @default(uuid())
|
|
403
|
+
clientId String // Client identifier (e.g., machine ID, user ID)
|
|
404
|
+
agentName String
|
|
405
|
+
agentDescription String?
|
|
406
|
+
messages Json // Array of { role: 'user' | 'assistant', content: string }
|
|
407
|
+
createdAt DateTime @default(now())
|
|
408
|
+
lastMessageAt DateTime @default(now())
|
|
409
|
+
updatedAt DateTime @updatedAt
|
|
410
|
+
|
|
411
|
+
@@map("chat_history")
|
|
412
|
+
@@index([clientId])
|
|
413
|
+
@@index([clientId, lastMessageAt])
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// ====== DEVKIT AGENT & TOOL MANAGEMENT ======
|
|
417
|
+
|
|
418
|
+
model DevKitAgent {
|
|
419
|
+
id String @id @default(uuid())
|
|
420
|
+
name String
|
|
421
|
+
slug String @unique
|
|
422
|
+
description String?
|
|
423
|
+
type String // lead_agent, education_agent, custom, etc.
|
|
424
|
+
model String // gpt-4, claude-3, etc.
|
|
425
|
+
config Json @default("{}") // { prompt, temperature, maxTokens, etc. }
|
|
426
|
+
createdAt DateTime @default(now())
|
|
427
|
+
updatedAt DateTime @updatedAt
|
|
428
|
+
|
|
429
|
+
// Relations
|
|
430
|
+
tools DevKitAgentTool[]
|
|
431
|
+
|
|
432
|
+
@@map("devkit_agents")
|
|
433
|
+
@@index([slug])
|
|
434
|
+
@@index([type])
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
model DevKitTool {
|
|
438
|
+
id String @id @default(uuid())
|
|
439
|
+
name String
|
|
440
|
+
kind String // http, email, vector, database, etc.
|
|
441
|
+
config Json @default("{}") // Flexible config per kind
|
|
442
|
+
enabled Boolean @default(true)
|
|
443
|
+
createdAt DateTime @default(now())
|
|
444
|
+
updatedAt DateTime @updatedAt
|
|
445
|
+
|
|
446
|
+
// Relations
|
|
447
|
+
agents DevKitAgentTool[]
|
|
448
|
+
|
|
449
|
+
@@map("devkit_tools")
|
|
450
|
+
@@index([kind])
|
|
451
|
+
@@index([enabled])
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
model DevKitAgentTool {
|
|
455
|
+
id String @id @default(uuid())
|
|
456
|
+
agentId String
|
|
457
|
+
toolId String
|
|
458
|
+
configOverride Json? // Optional per-agent tool configuration
|
|
459
|
+
createdAt DateTime @default(now())
|
|
460
|
+
|
|
461
|
+
// Relations
|
|
462
|
+
agent DevKitAgent @relation(fields: [agentId], references: [id], onDelete: Cascade)
|
|
463
|
+
tool DevKitTool @relation(fields: [toolId], references: [id], onDelete: Cascade)
|
|
464
|
+
|
|
465
|
+
@@unique([agentId, toolId])
|
|
466
|
+
@@map("devkit_agent_tools")
|
|
467
|
+
@@index([agentId])
|
|
468
|
+
@@index([toolId])
|
|
469
|
+
}
|
|
@@ -20,8 +20,31 @@ if (!fs.existsSync(packageJson)) {
|
|
|
20
20
|
process.exit(0); // No gateway in this install
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
const prismaSchema = path.join(__dirname, '..', 'prisma', 'schema.prisma');
|
|
24
|
+
|
|
25
|
+
function ensurePrismaClient() {
|
|
26
|
+
if (!fs.existsSync(prismaSchema)) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
console.log('🔧 Prisma: generating client for Gateway (global 4runr-os install)...');
|
|
31
|
+
execSync('npx prisma generate --schema=../../prisma/schema.prisma', {
|
|
32
|
+
cwd: gatewayDir,
|
|
33
|
+
stdio: 'inherit',
|
|
34
|
+
shell: process.platform === 'win32',
|
|
35
|
+
});
|
|
36
|
+
console.log('✓ Prisma client ready for Gateway');
|
|
37
|
+
} catch (err) {
|
|
38
|
+
console.warn(
|
|
39
|
+
'⚠️ prisma generate failed. OS auto-start Gateway may fail until you run:\n' +
|
|
40
|
+
' cd apps/gateway && npx prisma generate --schema=../../prisma/schema.prisma',
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
23
45
|
if (fs.existsSync(nodeModules) && fs.readdirSync(nodeModules).length > 0) {
|
|
24
|
-
|
|
46
|
+
ensurePrismaClient();
|
|
47
|
+
process.exit(0); // Deps already present (e.g. from prepublish) — still (re)generate Prisma
|
|
25
48
|
}
|
|
26
49
|
|
|
27
50
|
try {
|
|
@@ -36,3 +59,5 @@ try {
|
|
|
36
59
|
console.warn('⚠️ Gateway dependency install failed. Start gateway from repo with: cd apps/gateway && npm start');
|
|
37
60
|
// Don't fail the main install
|
|
38
61
|
}
|
|
62
|
+
|
|
63
|
+
ensurePrismaClient();
|