@pga-ai/server 0.8.0
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/dist/PGAServer.d.ts +67 -0
- package/dist/PGAServer.d.ts.map +1 -0
- package/dist/PGAServer.js +133 -0
- package/dist/PGAServer.js.map +1 -0
- package/dist/auth/HMACVerifier.d.ts +6 -0
- package/dist/auth/HMACVerifier.d.ts.map +1 -0
- package/dist/auth/HMACVerifier.js +19 -0
- package/dist/auth/HMACVerifier.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/routes/genomes.d.ts +4 -0
- package/dist/routes/genomes.d.ts.map +1 -0
- package/dist/routes/genomes.js +78 -0
- package/dist/routes/genomes.js.map +1 -0
- package/dist/routes/health.d.ts +4 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +10 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/prompts.d.ts +4 -0
- package/dist/routes/prompts.d.ts.map +1 -0
- package/dist/routes/prompts.js +21 -0
- package/dist/routes/prompts.js.map +1 -0
- package/dist/routes/reports.d.ts +4 -0
- package/dist/routes/reports.d.ts.map +1 -0
- package/dist/routes/reports.js +40 -0
- package/dist/routes/reports.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type FastifyInstance } from 'fastify';
|
|
2
|
+
import { GenomeInstance } from '@pga-ai/core';
|
|
3
|
+
import type { LLMAdapter, StorageAdapter, WrapOptions } from '@pga-ai/core';
|
|
4
|
+
import type { GeneCategory } from '@pga-ai/core';
|
|
5
|
+
export interface PGAServerConfig {
|
|
6
|
+
storage?: StorageAdapter;
|
|
7
|
+
llm?: LLMAdapter;
|
|
8
|
+
adminApiKey: string;
|
|
9
|
+
port?: number;
|
|
10
|
+
host?: string;
|
|
11
|
+
logger?: boolean;
|
|
12
|
+
rateLimit?: {
|
|
13
|
+
max: number;
|
|
14
|
+
timeWindow: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface RegisterGenomeOptions {
|
|
18
|
+
name: string;
|
|
19
|
+
systemPrompt: string;
|
|
20
|
+
protect?: string[];
|
|
21
|
+
evolve?: Array<string | {
|
|
22
|
+
category: GeneCategory;
|
|
23
|
+
content: string;
|
|
24
|
+
}>;
|
|
25
|
+
adapt?: Array<string | {
|
|
26
|
+
trait: string;
|
|
27
|
+
content: string;
|
|
28
|
+
}>;
|
|
29
|
+
evolution?: WrapOptions['evolution'];
|
|
30
|
+
}
|
|
31
|
+
export interface GenomeEntry {
|
|
32
|
+
instance: GenomeInstance;
|
|
33
|
+
secret: string;
|
|
34
|
+
name: string;
|
|
35
|
+
createdAt: Date;
|
|
36
|
+
}
|
|
37
|
+
export declare class PGAServer {
|
|
38
|
+
private config;
|
|
39
|
+
private app;
|
|
40
|
+
private pga;
|
|
41
|
+
private genomes;
|
|
42
|
+
private storage;
|
|
43
|
+
private llm;
|
|
44
|
+
private startTime;
|
|
45
|
+
readonly adminApiKey: string;
|
|
46
|
+
readonly port: number;
|
|
47
|
+
constructor(config: PGAServerConfig);
|
|
48
|
+
start(port?: number): Promise<void>;
|
|
49
|
+
stop(): Promise<void>;
|
|
50
|
+
getApp(): FastifyInstance;
|
|
51
|
+
registerGenome(options: RegisterGenomeOptions): Promise<{
|
|
52
|
+
genomeId: string;
|
|
53
|
+
secret: string;
|
|
54
|
+
}>;
|
|
55
|
+
removeGenome(genomeId: string): Promise<boolean>;
|
|
56
|
+
getGenomeEntry(genomeId: string): GenomeEntry | undefined;
|
|
57
|
+
listGenomes(): Array<{
|
|
58
|
+
genomeId: string;
|
|
59
|
+
name: string;
|
|
60
|
+
createdAt: Date;
|
|
61
|
+
}>;
|
|
62
|
+
getUptime(): number;
|
|
63
|
+
getGenomeCount(): number;
|
|
64
|
+
verifyAdminKey(key: string | undefined): boolean;
|
|
65
|
+
verifyGenomeSecret(genomeId: string, bearer: string | undefined): boolean;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=PGAServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PGAServer.d.ts","sourceRoot":"","sources":["../src/PGAServer.ts"],"names":[],"mappings":"AAkBA,OAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,EAAO,cAAc,EAAyC,MAAM,cAAc,CAAC;AAC1F,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AASjD,MAAM,WAAW,eAAe;IAE5B,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB,GAAG,CAAC,EAAE,UAAU,CAAC;IAEjB,WAAW,EAAE,MAAM,CAAC;IAEpB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,SAAS,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CACnD;AAED,MAAM,WAAW,qBAAqB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG;QAAE,QAAQ,EAAE,YAAY,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,SAAS,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,WAAW;IACxB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;CACnB;AAcD,qBAAa,SAAS;IAWN,OAAO,CAAC,MAAM;IAV1B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAO;IAClB,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,SAAS,CAAc;IAE/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEF,MAAM,EAAE,eAAe;IAYrC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCnC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,MAAM,IAAI,eAAe;IASnB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAkC7F,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYtD,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAOzD,WAAW,IAAI,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,CAAC;IAWzE,SAAS,IAAI,MAAM;IAOnB,cAAc,IAAI,MAAM;IASxB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO;IAWhD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO;CAU5E"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import Fastify from 'fastify';
|
|
3
|
+
import { PGA, GenomeBuilder, InMemoryStorageAdapter } from '@pga-ai/core';
|
|
4
|
+
import { HMACVerifier } from './auth/HMACVerifier.js';
|
|
5
|
+
import { registerHealthRoutes } from './routes/health.js';
|
|
6
|
+
import { registerGenomeRoutes } from './routes/genomes.js';
|
|
7
|
+
import { registerPromptRoutes } from './routes/prompts.js';
|
|
8
|
+
import { registerReportRoutes } from './routes/reports.js';
|
|
9
|
+
class NoopLLMAdapter {
|
|
10
|
+
name = 'noop';
|
|
11
|
+
model = 'noop';
|
|
12
|
+
async chat() {
|
|
13
|
+
return { content: '', usage: { inputTokens: 0, outputTokens: 0 } };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class PGAServer {
|
|
17
|
+
config;
|
|
18
|
+
app;
|
|
19
|
+
pga;
|
|
20
|
+
genomes = new Map();
|
|
21
|
+
storage;
|
|
22
|
+
llm;
|
|
23
|
+
startTime = Date.now();
|
|
24
|
+
adminApiKey;
|
|
25
|
+
port;
|
|
26
|
+
constructor(config) {
|
|
27
|
+
this.config = config;
|
|
28
|
+
this.adminApiKey = config.adminApiKey;
|
|
29
|
+
this.port = config.port ?? 4444;
|
|
30
|
+
this.storage = config.storage ?? new InMemoryStorageAdapter();
|
|
31
|
+
this.llm = config.llm ?? new NoopLLMAdapter();
|
|
32
|
+
this.app = Fastify({ logger: config.logger ?? true });
|
|
33
|
+
}
|
|
34
|
+
async start(port) {
|
|
35
|
+
const listenPort = port ?? this.port;
|
|
36
|
+
this.pga = new PGA({
|
|
37
|
+
llm: this.llm,
|
|
38
|
+
storage: this.storage,
|
|
39
|
+
monitoring: { enabled: true, enableCostTracking: true, enableAuditLogs: true },
|
|
40
|
+
});
|
|
41
|
+
await this.pga.initialize();
|
|
42
|
+
if (this.config.rateLimit) {
|
|
43
|
+
const rateLimitPlugin = await import('@fastify/rate-limit');
|
|
44
|
+
await this.app.register(rateLimitPlugin.default, {
|
|
45
|
+
max: this.config.rateLimit.max,
|
|
46
|
+
timeWindow: this.config.rateLimit.timeWindow,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
registerHealthRoutes(this.app, this);
|
|
50
|
+
registerGenomeRoutes(this.app, this);
|
|
51
|
+
registerPromptRoutes(this.app, this);
|
|
52
|
+
registerReportRoutes(this.app, this);
|
|
53
|
+
await this.app.listen({ port: listenPort, host: this.config.host ?? '127.0.0.1' });
|
|
54
|
+
this.startTime = Date.now();
|
|
55
|
+
}
|
|
56
|
+
async stop() {
|
|
57
|
+
await this.app.close();
|
|
58
|
+
this.pga.shutdown();
|
|
59
|
+
}
|
|
60
|
+
getApp() {
|
|
61
|
+
return this.app;
|
|
62
|
+
}
|
|
63
|
+
async registerGenome(options) {
|
|
64
|
+
const genome = GenomeBuilder.build({
|
|
65
|
+
name: options.name,
|
|
66
|
+
systemPrompt: options.systemPrompt,
|
|
67
|
+
protect: options.protect,
|
|
68
|
+
evolve: options.evolve,
|
|
69
|
+
adapt: options.adapt,
|
|
70
|
+
evolution: options.evolution,
|
|
71
|
+
});
|
|
72
|
+
await this.storage.saveGenome(genome);
|
|
73
|
+
const instance = await this.pga.loadGenome(genome.id);
|
|
74
|
+
if (!instance) {
|
|
75
|
+
throw new Error(`Failed to create genome: ${options.name}`);
|
|
76
|
+
}
|
|
77
|
+
const secret = HMACVerifier.generateSecret();
|
|
78
|
+
this.genomes.set(genome.id, {
|
|
79
|
+
instance,
|
|
80
|
+
secret,
|
|
81
|
+
name: options.name,
|
|
82
|
+
createdAt: new Date(),
|
|
83
|
+
});
|
|
84
|
+
return { genomeId: genome.id, secret };
|
|
85
|
+
}
|
|
86
|
+
async removeGenome(genomeId) {
|
|
87
|
+
const entry = this.genomes.get(genomeId);
|
|
88
|
+
if (!entry)
|
|
89
|
+
return false;
|
|
90
|
+
await this.pga.deleteGenome(genomeId);
|
|
91
|
+
this.genomes.delete(genomeId);
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
getGenomeEntry(genomeId) {
|
|
95
|
+
return this.genomes.get(genomeId);
|
|
96
|
+
}
|
|
97
|
+
listGenomes() {
|
|
98
|
+
return Array.from(this.genomes.entries()).map(([id, entry]) => ({
|
|
99
|
+
genomeId: id,
|
|
100
|
+
name: entry.name,
|
|
101
|
+
createdAt: entry.createdAt,
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
getUptime() {
|
|
105
|
+
return Math.floor((Date.now() - this.startTime) / 1000);
|
|
106
|
+
}
|
|
107
|
+
getGenomeCount() {
|
|
108
|
+
return this.genomes.size;
|
|
109
|
+
}
|
|
110
|
+
verifyAdminKey(key) {
|
|
111
|
+
if (!key)
|
|
112
|
+
return false;
|
|
113
|
+
const a = Buffer.from(key);
|
|
114
|
+
const b = Buffer.from(this.adminApiKey);
|
|
115
|
+
if (a.length !== b.length)
|
|
116
|
+
return false;
|
|
117
|
+
return timingSafeEqual(a, b);
|
|
118
|
+
}
|
|
119
|
+
verifyGenomeSecret(genomeId, bearer) {
|
|
120
|
+
if (!bearer)
|
|
121
|
+
return false;
|
|
122
|
+
const token = bearer.startsWith('Bearer ') ? bearer.slice(7) : bearer;
|
|
123
|
+
const entry = this.genomes.get(genomeId);
|
|
124
|
+
if (!entry)
|
|
125
|
+
return false;
|
|
126
|
+
const a = Buffer.from(token);
|
|
127
|
+
const b = Buffer.from(entry.secret);
|
|
128
|
+
if (a.length !== b.length)
|
|
129
|
+
return false;
|
|
130
|
+
return timingSafeEqual(a, b);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=PGAServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PGAServer.js","sourceRoot":"","sources":["../src/PGAServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HMACVerifier.d.ts","sourceRoot":"","sources":["../../src/auth/HMACVerifier.ts"],"names":[],"mappings":"AAeA,qBAAa,YAAY;IAIrB,MAAM,CAAC,cAAc,IAAI,MAAM;IAW/B,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAiBpD,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;CAa7E"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
export class HMACVerifier {
|
|
3
|
+
static generateSecret() {
|
|
4
|
+
return randomBytes(32).toString('hex');
|
|
5
|
+
}
|
|
6
|
+
static sign(secret, payload) {
|
|
7
|
+
return createHmac('sha256', secret)
|
|
8
|
+
.update(payload)
|
|
9
|
+
.digest('hex');
|
|
10
|
+
}
|
|
11
|
+
static verify(secret, payload, signature) {
|
|
12
|
+
const expected = HMACVerifier.sign(secret, payload);
|
|
13
|
+
if (expected.length !== signature.length) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(signature, 'hex'));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=HMACVerifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HMACVerifier.js","sourceRoot":"","sources":["../../src/auth/HMACVerifier.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,OAAO,YAAY;IAIrB,MAAM,CAAC,cAAc;QACjB,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IASD,MAAM,CAAC,IAAI,CAAC,MAAc,EAAE,OAAe;QACvC,OAAO,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC;aAC9B,MAAM,CAAC,OAAO,CAAC;aACf,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAaD,MAAM,CAAC,MAAM,CAAC,MAAc,EAAE,OAAe,EAAE,SAAiB;QAC5D,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAGpD,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,OAAO,eAAe,CAClB,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,EAC5B,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAChC,CAAC;IACN,CAAC;CACJ"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC1F,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genomes.d.ts","sourceRoot":"","sources":["../../src/routes/genomes.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAkHlF"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export function registerGenomeRoutes(app, server) {
|
|
2
|
+
app.post('/api/genomes', async (request, reply) => {
|
|
3
|
+
const apiKey = request.headers['x-pga-admin-key'];
|
|
4
|
+
if (!server.verifyAdminKey(apiKey)) {
|
|
5
|
+
return reply.status(401).send({ error: 'Invalid or missing admin API key' });
|
|
6
|
+
}
|
|
7
|
+
const body = request.body;
|
|
8
|
+
if (!body.name || !body.systemPrompt) {
|
|
9
|
+
return reply.status(400).send({ error: 'name and systemPrompt are required' });
|
|
10
|
+
}
|
|
11
|
+
const result = await server.registerGenome({
|
|
12
|
+
name: body.name,
|
|
13
|
+
systemPrompt: body.systemPrompt,
|
|
14
|
+
protect: body.protect,
|
|
15
|
+
evolve: body.evolve,
|
|
16
|
+
adapt: body.adapt,
|
|
17
|
+
});
|
|
18
|
+
return reply.status(201).send(result);
|
|
19
|
+
});
|
|
20
|
+
app.get('/api/genomes', async (request, reply) => {
|
|
21
|
+
const apiKey = request.headers['x-pga-admin-key'];
|
|
22
|
+
if (!server.verifyAdminKey(apiKey)) {
|
|
23
|
+
return reply.status(401).send({ error: 'Invalid or missing admin API key' });
|
|
24
|
+
}
|
|
25
|
+
return server.listGenomes();
|
|
26
|
+
});
|
|
27
|
+
app.get('/api/genomes/:id', async (request, reply) => {
|
|
28
|
+
const apiKey = request.headers['x-pga-admin-key'];
|
|
29
|
+
if (!server.verifyAdminKey(apiKey)) {
|
|
30
|
+
return reply.status(401).send({ error: 'Invalid or missing admin API key' });
|
|
31
|
+
}
|
|
32
|
+
const entry = server.getGenomeEntry(request.params.id);
|
|
33
|
+
if (!entry) {
|
|
34
|
+
return reply.status(404).send({ error: 'Genome not found' });
|
|
35
|
+
}
|
|
36
|
+
const analytics = await entry.instance.getAnalytics();
|
|
37
|
+
return {
|
|
38
|
+
genomeId: request.params.id,
|
|
39
|
+
name: entry.name,
|
|
40
|
+
createdAt: entry.createdAt,
|
|
41
|
+
analytics,
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
app.delete('/api/genomes/:id', async (request, reply) => {
|
|
45
|
+
const apiKey = request.headers['x-pga-admin-key'];
|
|
46
|
+
if (!server.verifyAdminKey(apiKey)) {
|
|
47
|
+
return reply.status(401).send({ error: 'Invalid or missing admin API key' });
|
|
48
|
+
}
|
|
49
|
+
const removed = await server.removeGenome(request.params.id);
|
|
50
|
+
if (!removed) {
|
|
51
|
+
return reply.status(404).send({ error: 'Genome not found' });
|
|
52
|
+
}
|
|
53
|
+
return { deleted: true };
|
|
54
|
+
});
|
|
55
|
+
app.get('/api/genomes/:id/drift', async (request, reply) => {
|
|
56
|
+
const apiKey = request.headers['x-pga-admin-key'];
|
|
57
|
+
if (!server.verifyAdminKey(apiKey)) {
|
|
58
|
+
return reply.status(401).send({ error: 'Invalid or missing admin API key' });
|
|
59
|
+
}
|
|
60
|
+
const entry = server.getGenomeEntry(request.params.id);
|
|
61
|
+
if (!entry) {
|
|
62
|
+
return reply.status(404).send({ error: 'Genome not found' });
|
|
63
|
+
}
|
|
64
|
+
return entry.instance.getDriftAnalysis();
|
|
65
|
+
});
|
|
66
|
+
app.get('/api/genomes/:id/health', async (request, reply) => {
|
|
67
|
+
const apiKey = request.headers['x-pga-admin-key'];
|
|
68
|
+
if (!server.verifyAdminKey(apiKey)) {
|
|
69
|
+
return reply.status(401).send({ error: 'Invalid or missing admin API key' });
|
|
70
|
+
}
|
|
71
|
+
const entry = server.getGenomeEntry(request.params.id);
|
|
72
|
+
if (!entry) {
|
|
73
|
+
return reply.status(404).send({ error: 'Genome not found' });
|
|
74
|
+
}
|
|
75
|
+
return entry.instance.getEvolutionHealth();
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=genomes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genomes.js","sourceRoot":"","sources":["../../src/routes/genomes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAQlF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,oBAAoB,CAAC,GAAoB,EAAE,MAAiB;IACxE,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,IAAI,EAAE;QAC9B,OAAO;YACH,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,MAAM,CAAC,cAAc,EAAE;YAChC,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE;SAC7B,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/routes/prompts.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAmClF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function registerPromptRoutes(app, server) {
|
|
2
|
+
app.get('/api/genomes/:id/prompt', async (request, reply) => {
|
|
3
|
+
const { id } = request.params;
|
|
4
|
+
const auth = request.headers.authorization;
|
|
5
|
+
if (!server.verifyGenomeSecret(id, auth)) {
|
|
6
|
+
return reply.status(401).send({ error: 'Invalid or missing genome secret' });
|
|
7
|
+
}
|
|
8
|
+
const entry = server.getGenomeEntry(id);
|
|
9
|
+
if (!entry) {
|
|
10
|
+
return reply.status(404).send({ error: 'Genome not found' });
|
|
11
|
+
}
|
|
12
|
+
const { userId, taskType } = request.query;
|
|
13
|
+
const prompt = await entry.instance.assemblePrompt({ userId, taskType }, '');
|
|
14
|
+
reply.header('Cache-Control', 'private, max-age=60');
|
|
15
|
+
return {
|
|
16
|
+
prompt,
|
|
17
|
+
genomeId: id,
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/routes/prompts.ts"],"names":[],"mappings":"AAgBA,MAAM,UAAU,oBAAoB,CAAC,GAAoB,EAAE,MAAiB;IAExE,GAAG,CAAC,GAAG,CAGJ,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACnD,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAG9B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC,CAAC;QACjF,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,KAA+C,CAAC;QAGrF,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,cAAc,CAC9C,EAAE,MAAM,EAAE,QAAQ,EAAE,EACpB,EAAE,CACL,CAAC;QAGF,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,qBAAqB,CAAC,CAAC;QAErD,OAAO;YACH,MAAM;YACN,QAAQ,EAAE,EAAE;SACf,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reports.d.ts","sourceRoot":"","sources":["../../src/routes/reports.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAwDlF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { HMACVerifier } from '../auth/HMACVerifier.js';
|
|
2
|
+
export function registerReportRoutes(app, server) {
|
|
3
|
+
app.post('/api/genomes/:id/report', async (request, reply) => {
|
|
4
|
+
const { id } = request.params;
|
|
5
|
+
const entry = server.getGenomeEntry(id);
|
|
6
|
+
if (!entry) {
|
|
7
|
+
return reply.status(404).send({ error: 'Genome not found' });
|
|
8
|
+
}
|
|
9
|
+
const signature = request.headers['x-pga-signature'];
|
|
10
|
+
if (!signature) {
|
|
11
|
+
return reply.status(401).send({ error: 'Missing X-PGA-Signature header' });
|
|
12
|
+
}
|
|
13
|
+
const rawBody = JSON.stringify(request.body);
|
|
14
|
+
if (!HMACVerifier.verify(entry.secret, rawBody, signature)) {
|
|
15
|
+
return reply.status(401).send({ error: 'Invalid HMAC signature' });
|
|
16
|
+
}
|
|
17
|
+
const body = request.body;
|
|
18
|
+
if (typeof body.success !== 'boolean' || typeof body.latencyMs !== 'number') {
|
|
19
|
+
return reply.status(400).send({ error: 'success (boolean) and latencyMs (number) are required' });
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
await entry.instance.reportExternalMetrics({
|
|
23
|
+
userId: body.userId,
|
|
24
|
+
success: body.success,
|
|
25
|
+
latencyMs: body.latencyMs,
|
|
26
|
+
inputTokens: body.inputTokens ?? 0,
|
|
27
|
+
outputTokens: body.outputTokens ?? 0,
|
|
28
|
+
taskType: body.taskType,
|
|
29
|
+
quality: body.quality,
|
|
30
|
+
feedback: body.feedback,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
request.log.error(err, 'Failed to process metrics');
|
|
35
|
+
return reply.status(500).send({ error: 'Failed to process metrics' });
|
|
36
|
+
}
|
|
37
|
+
return { recorded: true };
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=reports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reports.js","sourceRoot":"","sources":["../../src/routes/reports.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,MAAM,UAAU,oBAAoB,CAAC,GAAoB,EAAE,MAAiB;IAExE,GAAG,CAAC,IAAI,CAA6B,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACrF,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAE9B,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACjE,CAAC;QAGD,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAuB,CAAC;QAC3E,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gCAAgC,EAAE,CAAC,CAAC;QAC/E,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;YACzD,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,CAAC,IASpB,CAAC;QAGF,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC1E,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uDAAuD,EAAE,CAAC,CAAC;QACtG,CAAC;QAGD,IAAI,CAAC;YACD,MAAM,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC;gBACvC,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC;gBAClC,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,CAAC;gBACpC,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;aAC1B,CAAC,CAAC;QACP,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,2BAA2B,CAAC,CAAC;YACpD,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC1E,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC9B,CAAC,CAAC,CAAC;AACP,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pga-ai/server",
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "GSEP Evolution Server — Secure Pull/Push API for external agents",
|
|
5
|
+
"author": "Luis Alfredo Velasquez Duran <contact@gsepcore.com>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://gsepcore.com",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/LuisvelMarketer/pga-platform",
|
|
11
|
+
"directory": "packages/server"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/LuisvelMarketer/pga-platform/issues"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"import": "./dist/index.js",
|
|
22
|
+
"types": "./dist/index.d.ts"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc",
|
|
30
|
+
"dev": "tsc --watch",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"test:watch": "vitest",
|
|
33
|
+
"clean": "rm -rf dist",
|
|
34
|
+
"typecheck": "tsc --noEmit"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@pga-ai/core": "*",
|
|
38
|
+
"fastify": "^5.3.3",
|
|
39
|
+
"@fastify/rate-limit": "^10.2.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"typescript": "^5.4.5",
|
|
43
|
+
"vitest": "^3.2.4"
|
|
44
|
+
},
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
}
|
|
48
|
+
}
|