@hexis-ai/engram-server 0.1.0 → 0.1.2

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.
@@ -8,6 +8,8 @@ import { type StorageAdapter } from "../storage";
8
8
  */
9
9
  export interface SqlClient {
10
10
  <T = Record<string, unknown>>(strings: TemplateStringsArray, ...values: unknown[]): Promise<T[]>;
11
+ /** Raw query for DDL / multi-statement strings. */
12
+ unsafe: (query: string) => Promise<unknown>;
11
13
  }
12
14
  export interface PostgresAdapterOptions {
13
15
  /** Workspace scope baked into every row. Required for multi-tenant isolation. */
@@ -20,9 +22,7 @@ export declare class PostgresAdapter implements StorageAdapter {
20
22
  constructor(opts: PostgresAdapterOptions);
21
23
  /**
22
24
  * Create the schema. Call once at boot. Safe to invoke repeatedly.
23
- * Postgres pg-tag template clients accept multi-statement strings via
24
- * `sql.unsafe()` in the real driver; for portability we issue them
25
- * separately so any tagged-template impl works.
25
+ * Uses `sql.unsafe()` to ship the multi-statement DDL as a single batch.
26
26
  */
27
27
  ensureSchema(): Promise<void>;
28
28
  createSession(init: SessionInit & {
@@ -34,16 +34,10 @@ export class PostgresAdapter {
34
34
  }
35
35
  /**
36
36
  * Create the schema. Call once at boot. Safe to invoke repeatedly.
37
- * Postgres pg-tag template clients accept multi-statement strings via
38
- * `sql.unsafe()` in the real driver; for portability we issue them
39
- * separately so any tagged-template impl works.
37
+ * Uses `sql.unsafe()` to ship the multi-statement DDL as a single batch.
40
38
  */
41
39
  async ensureSchema() {
42
- const stmts = SCHEMA_SQL.split(/;\s*\n/).map((s) => s.trim()).filter(Boolean);
43
- for (const stmt of stmts) {
44
- // Tagged-template invocation with no interpolations.
45
- await this.sql([stmt + ";"]);
46
- }
40
+ await this.sql.unsafe(SCHEMA_SQL);
47
41
  }
48
42
  async createSession(init) {
49
43
  await this.sql `
package/dist/main.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ declare const _default: {
2
+ port: number;
3
+ fetch: (request: Request, Env?: unknown, executionCtx?: import("hono").ExecutionContext) => Response | Promise<Response>;
4
+ };
5
+ export default _default;
package/dist/main.js ADDED
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Production entrypoint.
3
+ *
4
+ * Reads configuration from environment:
5
+ *
6
+ * ENGRAM_API_KEY required single bearer key. Multi-tenant deploys
7
+ * should swap this for a real key store.
8
+ * PORT default 8080 HTTP listen port.
9
+ * DATABASE_URL optional if set, uses PostgresAdapter; otherwise
10
+ * falls back to InMemoryAdapter (NOT
11
+ * durable across restarts).
12
+ * DATABASE_SOCKET_PATH optional Cloud SQL Auth Proxy unix socket dir.
13
+ * When set, postgres connects via
14
+ * `host=<DATABASE_SOCKET_PATH>`.
15
+ * ENGRAM_WORKSPACE_ID default "default"
16
+ * workspace id baked into the postgres
17
+ * adapter for this single-tenant deploy.
18
+ */
19
+ import { createServer } from "./server";
20
+ import { InMemoryAdapter } from "./adapters/memory";
21
+ import { PostgresAdapter } from "./adapters/postgres";
22
+ const PORT = Number(process.env.PORT ?? 8080);
23
+ const API_KEY = process.env.ENGRAM_API_KEY;
24
+ const WORKSPACE_ID = process.env.ENGRAM_WORKSPACE_ID ?? "default";
25
+ const DATABASE_URL = process.env.DATABASE_URL;
26
+ const DATABASE_SOCKET_PATH = process.env.DATABASE_SOCKET_PATH;
27
+ if (!API_KEY) {
28
+ console.error("[engram-server] ENGRAM_API_KEY is required");
29
+ process.exit(1);
30
+ }
31
+ const storage = await (async () => {
32
+ if (!DATABASE_URL) {
33
+ console.warn("[engram-server] DATABASE_URL not set — using InMemoryAdapter (data is volatile)");
34
+ return new InMemoryAdapter();
35
+ }
36
+ // postgres is a peer dep so we import it lazily; absence is a hard error here.
37
+ const { default: postgres } = await import("postgres");
38
+ const sql = DATABASE_SOCKET_PATH
39
+ ? postgres(DATABASE_URL, { host: DATABASE_SOCKET_PATH })
40
+ : postgres(DATABASE_URL);
41
+ const adapter = new PostgresAdapter({
42
+ workspaceId: WORKSPACE_ID,
43
+ sql: sql,
44
+ });
45
+ await adapter.ensureSchema();
46
+ console.log(`[engram-server] postgres adapter ready (workspace=${WORKSPACE_ID})`);
47
+ return adapter;
48
+ })();
49
+ const app = createServer({
50
+ auth: (key) => (key === API_KEY ? { workspaceId: WORKSPACE_ID, storage } : null),
51
+ });
52
+ console.log(`[engram-server] listening on :${PORT}`);
53
+ export default { port: PORT, fetch: app.fetch };
package/dist/server.js CHANGED
@@ -5,6 +5,19 @@ export function createServer(opts) {
5
5
  const defaultLimit = opts.defaultListLimit ?? 100;
6
6
  const maxLimit = opts.maxListLimit ?? 500;
7
7
  const app = new Hono();
8
+ // Unauthenticated service info. Useful for browser sanity checks and
9
+ // health probes (Cloud Run, k8s, uptime monitors).
10
+ app.get("/", (c) => c.json({
11
+ service: "@hexis-ai/engram-server",
12
+ ok: true,
13
+ routes: {
14
+ sessions: "POST/GET /v1/sessions",
15
+ sessionById: "GET /v1/sessions/:id",
16
+ events: "POST /v1/sessions/:id/events",
17
+ search: "POST /v1/search",
18
+ },
19
+ }));
20
+ app.get("/healthz", (c) => c.json({ ok: true }));
8
21
  app.use("/v1/*", async (c, next) => {
9
22
  const auth = c.req.header("authorization");
10
23
  const m = auth?.match(/^Bearer\s+(.+)$/i);
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@hexis-ai/engram-server",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Engram server: ingest agent session events, persist via a pluggable adapter, expose search.",
5
5
  "keywords": ["engram", "agents", "search", "hono", "postgres", "server"],
6
- "homepage": "https://github.com/hexis-ai/engram#readme",
6
+ "homepage": "https://github.com/hexis-ltd/engram#readme",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "git+https://github.com/hexis-ai/engram.git",
9
+ "url": "git+https://github.com/hexis-ltd/engram.git",
10
10
  "directory": "packages/server"
11
11
  },
12
- "bugs": "https://github.com/hexis-ai/engram/issues",
12
+ "bugs": "https://github.com/hexis-ltd/engram/issues",
13
13
  "author": "hexis ltd.",
14
14
  "license": "MIT",
15
15
  "type": "module",
@@ -41,8 +41,8 @@
41
41
  "dev": "bun --hot src/dev.ts"
42
42
  },
43
43
  "dependencies": {
44
- "@hexis-ai/engram-core": "workspace:*",
45
- "@hexis-ai/engram-sdk": "workspace:*",
44
+ "@hexis-ai/engram-core": "^0.1.2",
45
+ "@hexis-ai/engram-sdk": "^0.1.2",
46
46
  "hono": "^4.6.0"
47
47
  },
48
48
  "peerDependencies": {
@@ -51,6 +51,9 @@
51
51
  "peerDependenciesMeta": {
52
52
  "postgres": { "optional": true }
53
53
  },
54
+ "devDependencies": {
55
+ "postgres": "^3.4.0"
56
+ },
54
57
  "publishConfig": {
55
58
  "access": "public"
56
59
  }