@hexis-ai/engram-server 0.2.0 → 0.3.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/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/openapi.d.ts +8 -0
- package/dist/openapi.js +296 -0
- package/openapi.json +937 -0
- package/package.json +4 -2
package/dist/index.d.ts
CHANGED
|
@@ -7,3 +7,4 @@ export { type KeyStore, type Workspace, type ApiKeyInfo, type IssuedKey, type Ke
|
|
|
7
7
|
export { InMemoryKeyStore } from "./adapters/memory-key-store";
|
|
8
8
|
export { PostgresKeyStore } from "./adapters/postgres-key-store";
|
|
9
9
|
export { createAdminRouter, type AdminOptions } from "./admin";
|
|
10
|
+
export { buildOpenApiDocument } from "./openapi";
|
package/dist/index.js
CHANGED
|
@@ -7,3 +7,4 @@ export { generateRawKey, hashKey, keyPrefix, isValidWorkspaceId, } from "./key-s
|
|
|
7
7
|
export { InMemoryKeyStore } from "./adapters/memory-key-store";
|
|
8
8
|
export { PostgresKeyStore } from "./adapters/postgres-key-store";
|
|
9
9
|
export { createAdminRouter } from "./admin";
|
|
10
|
+
export { buildOpenApiDocument } from "./openapi";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type Json = Record<string, unknown>;
|
|
2
|
+
/**
|
|
3
|
+
* Build the OpenAPI 3.1 document. Pure and deterministic — `gen-openapi.ts`
|
|
4
|
+
* writes its output to `openapi.json`, and `openapi.test.ts` asserts the
|
|
5
|
+
* committed file still matches.
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildOpenApiDocument(): Json;
|
|
8
|
+
export {};
|
package/dist/openapi.js
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI 3.1 document for the engram HTTP API, assembled from the same Zod
|
|
3
|
+
* schemas the server validates with (`src/schemas.ts`). The request-body
|
|
4
|
+
* contract therefore cannot drift from what the server actually accepts —
|
|
5
|
+
* a sync test (`test/openapi.test.ts`) fails the build if it does.
|
|
6
|
+
*
|
|
7
|
+
* This is the language-neutral contract artifact. Non-TypeScript engram SDK
|
|
8
|
+
* ports generate their wire types from `packages/server/openapi.json`
|
|
9
|
+
* (produced by `bun run gen:openapi`) instead of hand-mirroring the
|
|
10
|
+
* TypeScript interfaces in `@hexis-ai/engram-sdk`.
|
|
11
|
+
*
|
|
12
|
+
* `info.version` is the API version (the `/v1` surface), not the npm package
|
|
13
|
+
* version — it changes only when the wire contract changes.
|
|
14
|
+
*/
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
import { createWorkspaceSchema, eventBatchSchema, issueKeySchema, personCreateSchema, personUpdateSchema, searchRequestSchema, sessionInitSchema, } from "./schemas";
|
|
17
|
+
/** Convert a Zod schema to a JSON Schema object for an OpenAPI component. */
|
|
18
|
+
function toComponent(schema) {
|
|
19
|
+
const js = z.toJSONSchema(schema);
|
|
20
|
+
delete js.$schema;
|
|
21
|
+
return js;
|
|
22
|
+
}
|
|
23
|
+
const ref = (name) => ({ $ref: `#/components/schemas/${name}` });
|
|
24
|
+
const jsonBody = (schemaName, required = true) => ({
|
|
25
|
+
required,
|
|
26
|
+
content: { "application/json": { schema: ref(schemaName) } },
|
|
27
|
+
});
|
|
28
|
+
const pathParam = (name, description) => ({
|
|
29
|
+
name,
|
|
30
|
+
in: "path",
|
|
31
|
+
required: true,
|
|
32
|
+
schema: { type: "string" },
|
|
33
|
+
description,
|
|
34
|
+
});
|
|
35
|
+
const queryParam = (name, description, schema = { type: "string" }) => ({ name, in: "query", required: false, schema, description });
|
|
36
|
+
const res = (description) => ({ description });
|
|
37
|
+
/** Default security: a workspace API key. `/admin/v1` paths override this. */
|
|
38
|
+
const workspaceAuth = [{ workspaceKey: [] }];
|
|
39
|
+
const adminAuth = [{ adminToken: [] }];
|
|
40
|
+
const limitParam = queryParam("limit", "Page size; clamped server-side.", {
|
|
41
|
+
type: "integer",
|
|
42
|
+
minimum: 1,
|
|
43
|
+
});
|
|
44
|
+
const channelParam = queryParam("channel", "Filter by session channel.");
|
|
45
|
+
function buildPaths() {
|
|
46
|
+
return {
|
|
47
|
+
"/v1/me": {
|
|
48
|
+
get: {
|
|
49
|
+
summary: "Identity probe — the workspace the caller's key resolves to.",
|
|
50
|
+
responses: { "200": res("workspace id"), "401": res("unauthorized") },
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
"/v1/sessions": {
|
|
54
|
+
post: {
|
|
55
|
+
summary: "Create a session.",
|
|
56
|
+
requestBody: jsonBody("SessionInit"),
|
|
57
|
+
responses: {
|
|
58
|
+
"200": res("created session id"),
|
|
59
|
+
"400": res("invalid body"),
|
|
60
|
+
"401": res("unauthorized"),
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
get: {
|
|
64
|
+
summary: "List recent sessions plus their persons map.",
|
|
65
|
+
parameters: [limitParam, channelParam],
|
|
66
|
+
responses: { "200": res("session list envelope"), "401": res("unauthorized") },
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
"/v1/sessions/{id}": {
|
|
70
|
+
get: {
|
|
71
|
+
summary: "Fetch one session plus its persons map.",
|
|
72
|
+
parameters: [pathParam("id", "Session id.")],
|
|
73
|
+
responses: {
|
|
74
|
+
"200": res("session envelope"),
|
|
75
|
+
"404": res("session not found"),
|
|
76
|
+
"401": res("unauthorized"),
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
"/v1/sessions/{id}/events": {
|
|
81
|
+
post: {
|
|
82
|
+
summary: "Append events to a session.",
|
|
83
|
+
parameters: [pathParam("id", "Session id.")],
|
|
84
|
+
requestBody: jsonBody("EventBatch"),
|
|
85
|
+
responses: {
|
|
86
|
+
"204": res("appended"),
|
|
87
|
+
"400": res("invalid body"),
|
|
88
|
+
"404": res("session not found"),
|
|
89
|
+
"401": res("unauthorized"),
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
"/v1/search": {
|
|
94
|
+
post: {
|
|
95
|
+
summary: "Score the workspace corpus against a query session.",
|
|
96
|
+
requestBody: jsonBody("SearchRequest"),
|
|
97
|
+
responses: {
|
|
98
|
+
"200": res("scored results plus persons map"),
|
|
99
|
+
"400": res("invalid body"),
|
|
100
|
+
"404": res("query session not found"),
|
|
101
|
+
"401": res("unauthorized"),
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
"/v1/persons": {
|
|
106
|
+
post: {
|
|
107
|
+
summary: "Create a person (server allocates the id).",
|
|
108
|
+
requestBody: jsonBody("PersonCreate"),
|
|
109
|
+
responses: {
|
|
110
|
+
"201": res("created person"),
|
|
111
|
+
"400": res("invalid body"),
|
|
112
|
+
"401": res("unauthorized"),
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
get: {
|
|
116
|
+
summary: "List or free-text search persons.",
|
|
117
|
+
parameters: [limitParam, queryParam("q", "Free-text query over id + display_name.")],
|
|
118
|
+
responses: { "200": res("person list"), "401": res("unauthorized") },
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
"/v1/persons/{id}": {
|
|
122
|
+
put: {
|
|
123
|
+
summary: "Upsert a person at a caller-supplied id.",
|
|
124
|
+
parameters: [pathParam("id", "Person id.")],
|
|
125
|
+
requestBody: jsonBody("PersonCreate"),
|
|
126
|
+
responses: {
|
|
127
|
+
"200": res("upserted person"),
|
|
128
|
+
"400": res("invalid body"),
|
|
129
|
+
"401": res("unauthorized"),
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
patch: {
|
|
133
|
+
summary: "Patch a person's profile fields.",
|
|
134
|
+
parameters: [pathParam("id", "Person id.")],
|
|
135
|
+
requestBody: jsonBody("PersonUpdate"),
|
|
136
|
+
responses: {
|
|
137
|
+
"200": res("updated person"),
|
|
138
|
+
"400": res("invalid body"),
|
|
139
|
+
"404": res("person not found"),
|
|
140
|
+
"401": res("unauthorized"),
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
get: {
|
|
144
|
+
summary: "Fetch one person.",
|
|
145
|
+
parameters: [pathParam("id", "Person id.")],
|
|
146
|
+
responses: {
|
|
147
|
+
"200": res("person"),
|
|
148
|
+
"404": res("person not found"),
|
|
149
|
+
"401": res("unauthorized"),
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
"/v1/persons/{id}/sessions": {
|
|
154
|
+
get: {
|
|
155
|
+
summary: "Sessions this person participates in (or can view).",
|
|
156
|
+
parameters: [
|
|
157
|
+
pathParam("id", "Person id."),
|
|
158
|
+
limitParam,
|
|
159
|
+
channelParam,
|
|
160
|
+
queryParam("scope", "`participant` (default) or `viewable`.", {
|
|
161
|
+
type: "string",
|
|
162
|
+
enum: ["participant", "viewable"],
|
|
163
|
+
}),
|
|
164
|
+
],
|
|
165
|
+
responses: { "200": res("session list envelope"), "401": res("unauthorized") },
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
"/admin/v1/workspaces": {
|
|
169
|
+
post: {
|
|
170
|
+
summary: "Create a workspace (and, by default, an initial key).",
|
|
171
|
+
security: adminAuth,
|
|
172
|
+
requestBody: jsonBody("CreateWorkspace"),
|
|
173
|
+
responses: {
|
|
174
|
+
"200": res("workspace, plus key unless issueKey=false"),
|
|
175
|
+
"400": res("invalid body or workspace id"),
|
|
176
|
+
"401": res("unauthorized"),
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
get: {
|
|
180
|
+
summary: "List all workspaces.",
|
|
181
|
+
security: adminAuth,
|
|
182
|
+
responses: { "200": res("workspace list"), "401": res("unauthorized") },
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
"/admin/v1/workspaces/{id}": {
|
|
186
|
+
get: {
|
|
187
|
+
summary: "Fetch one workspace.",
|
|
188
|
+
security: adminAuth,
|
|
189
|
+
parameters: [pathParam("id", "Workspace id.")],
|
|
190
|
+
responses: {
|
|
191
|
+
"200": res("workspace"),
|
|
192
|
+
"404": res("workspace not found"),
|
|
193
|
+
"401": res("unauthorized"),
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
delete: {
|
|
197
|
+
summary: "Delete a workspace (cascades to keys, sessions, events).",
|
|
198
|
+
security: adminAuth,
|
|
199
|
+
parameters: [pathParam("id", "Workspace id.")],
|
|
200
|
+
responses: {
|
|
201
|
+
"204": res("deleted"),
|
|
202
|
+
"404": res("workspace not found"),
|
|
203
|
+
"401": res("unauthorized"),
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
"/admin/v1/workspaces/{id}/keys": {
|
|
208
|
+
post: {
|
|
209
|
+
summary: "Issue a new API key for a workspace.",
|
|
210
|
+
security: adminAuth,
|
|
211
|
+
parameters: [pathParam("id", "Workspace id.")],
|
|
212
|
+
requestBody: jsonBody("IssueKey", false),
|
|
213
|
+
responses: {
|
|
214
|
+
"200": res("issued key (raw key returned once)"),
|
|
215
|
+
"400": res("invalid body"),
|
|
216
|
+
"404": res("workspace not found"),
|
|
217
|
+
"401": res("unauthorized"),
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
get: {
|
|
221
|
+
summary: "List a workspace's API keys (hashes only).",
|
|
222
|
+
security: adminAuth,
|
|
223
|
+
parameters: [pathParam("id", "Workspace id.")],
|
|
224
|
+
responses: {
|
|
225
|
+
"200": res("key list"),
|
|
226
|
+
"404": res("workspace not found"),
|
|
227
|
+
"401": res("unauthorized"),
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
"/admin/v1/workspaces/{id}/keys/{keyId}": {
|
|
232
|
+
delete: {
|
|
233
|
+
summary: "Revoke an API key.",
|
|
234
|
+
security: adminAuth,
|
|
235
|
+
parameters: [
|
|
236
|
+
pathParam("id", "Workspace id."),
|
|
237
|
+
pathParam("keyId", "Key id."),
|
|
238
|
+
],
|
|
239
|
+
responses: {
|
|
240
|
+
"204": res("revoked (idempotent)"),
|
|
241
|
+
"404": res("key not found"),
|
|
242
|
+
"401": res("unauthorized"),
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Build the OpenAPI 3.1 document. Pure and deterministic — `gen-openapi.ts`
|
|
250
|
+
* writes its output to `openapi.json`, and `openapi.test.ts` asserts the
|
|
251
|
+
* committed file still matches.
|
|
252
|
+
*/
|
|
253
|
+
export function buildOpenApiDocument() {
|
|
254
|
+
return {
|
|
255
|
+
openapi: "3.1.0",
|
|
256
|
+
info: {
|
|
257
|
+
title: "engram-server",
|
|
258
|
+
version: "1.0",
|
|
259
|
+
description: "Cross-session retrieval for AI agents. Request bodies are derived " +
|
|
260
|
+
"from the server's Zod schemas (src/schemas.ts); response schemas " +
|
|
261
|
+
"are described by status only for now and are a planned follow-up.",
|
|
262
|
+
},
|
|
263
|
+
servers: [
|
|
264
|
+
{ url: "/", description: "relative to the deployed engram-server" },
|
|
265
|
+
],
|
|
266
|
+
security: workspaceAuth,
|
|
267
|
+
components: {
|
|
268
|
+
securitySchemes: {
|
|
269
|
+
workspaceKey: {
|
|
270
|
+
type: "http",
|
|
271
|
+
scheme: "bearer",
|
|
272
|
+
description: "Workspace API key (`eng_…`). Also accepted as the `X-Api-Key` header.",
|
|
273
|
+
},
|
|
274
|
+
adminToken: {
|
|
275
|
+
type: "apiKey",
|
|
276
|
+
in: "header",
|
|
277
|
+
name: "X-Admin-Token",
|
|
278
|
+
description: "Platform admin token for `/admin/v1/*`. Also accepted as `Authorization: Bearer`.",
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
schemas: {
|
|
282
|
+
SessionInit: toComponent(sessionInitSchema),
|
|
283
|
+
// `EventBatch` inlines the per-event shape. A standalone `SessionEvent`
|
|
284
|
+
// component (cross-`$ref`'d) is a planned follow-up alongside response
|
|
285
|
+
// schemas — zod's `toJSONSchema` inlines by default.
|
|
286
|
+
EventBatch: toComponent(eventBatchSchema),
|
|
287
|
+
PersonCreate: toComponent(personCreateSchema),
|
|
288
|
+
PersonUpdate: toComponent(personUpdateSchema),
|
|
289
|
+
SearchRequest: toComponent(searchRequestSchema),
|
|
290
|
+
CreateWorkspace: toComponent(createWorkspaceSchema),
|
|
291
|
+
IssueKey: toComponent(issueKeySchema),
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
paths: buildPaths(),
|
|
295
|
+
};
|
|
296
|
+
}
|
package/openapi.json
ADDED
|
@@ -0,0 +1,937 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openapi": "3.1.0",
|
|
3
|
+
"info": {
|
|
4
|
+
"title": "engram-server",
|
|
5
|
+
"version": "1.0",
|
|
6
|
+
"description": "Cross-session retrieval for AI agents. Request bodies are derived from the server's Zod schemas (src/schemas.ts); response schemas are described by status only for now and are a planned follow-up."
|
|
7
|
+
},
|
|
8
|
+
"servers": [
|
|
9
|
+
{
|
|
10
|
+
"url": "/",
|
|
11
|
+
"description": "relative to the deployed engram-server"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"security": [
|
|
15
|
+
{
|
|
16
|
+
"workspaceKey": []
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"components": {
|
|
20
|
+
"securitySchemes": {
|
|
21
|
+
"workspaceKey": {
|
|
22
|
+
"type": "http",
|
|
23
|
+
"scheme": "bearer",
|
|
24
|
+
"description": "Workspace API key (`eng_…`). Also accepted as the `X-Api-Key` header."
|
|
25
|
+
},
|
|
26
|
+
"adminToken": {
|
|
27
|
+
"type": "apiKey",
|
|
28
|
+
"in": "header",
|
|
29
|
+
"name": "X-Admin-Token",
|
|
30
|
+
"description": "Platform admin token for `/admin/v1/*`. Also accepted as `Authorization: Bearer`."
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"schemas": {
|
|
34
|
+
"SessionInit": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"properties": {
|
|
37
|
+
"id": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"minLength": 1
|
|
40
|
+
},
|
|
41
|
+
"title": {
|
|
42
|
+
"type": "string"
|
|
43
|
+
},
|
|
44
|
+
"channel": {
|
|
45
|
+
"type": "string"
|
|
46
|
+
},
|
|
47
|
+
"participants": {
|
|
48
|
+
"type": "array",
|
|
49
|
+
"items": {
|
|
50
|
+
"type": "string"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"viewable_by": {
|
|
54
|
+
"type": "array",
|
|
55
|
+
"items": {
|
|
56
|
+
"type": "string"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"additionalProperties": false
|
|
61
|
+
},
|
|
62
|
+
"EventBatch": {
|
|
63
|
+
"type": "object",
|
|
64
|
+
"properties": {
|
|
65
|
+
"events": {
|
|
66
|
+
"type": "array",
|
|
67
|
+
"items": {
|
|
68
|
+
"oneOf": [
|
|
69
|
+
{
|
|
70
|
+
"type": "object",
|
|
71
|
+
"properties": {
|
|
72
|
+
"type": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"const": "step"
|
|
75
|
+
},
|
|
76
|
+
"seq": {
|
|
77
|
+
"type": "integer",
|
|
78
|
+
"minimum": 0,
|
|
79
|
+
"maximum": 9007199254740991
|
|
80
|
+
},
|
|
81
|
+
"at": {
|
|
82
|
+
"type": "string"
|
|
83
|
+
},
|
|
84
|
+
"tool": {
|
|
85
|
+
"type": "string"
|
|
86
|
+
},
|
|
87
|
+
"resources": {
|
|
88
|
+
"type": "array",
|
|
89
|
+
"items": {
|
|
90
|
+
"type": "string"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"required": [
|
|
95
|
+
"type",
|
|
96
|
+
"seq",
|
|
97
|
+
"at",
|
|
98
|
+
"tool",
|
|
99
|
+
"resources"
|
|
100
|
+
],
|
|
101
|
+
"additionalProperties": false
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"type": "object",
|
|
105
|
+
"properties": {
|
|
106
|
+
"type": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"const": "participant"
|
|
109
|
+
},
|
|
110
|
+
"seq": {
|
|
111
|
+
"type": "integer",
|
|
112
|
+
"minimum": 0,
|
|
113
|
+
"maximum": 9007199254740991
|
|
114
|
+
},
|
|
115
|
+
"at": {
|
|
116
|
+
"type": "string"
|
|
117
|
+
},
|
|
118
|
+
"personId": {
|
|
119
|
+
"type": "string"
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"required": [
|
|
123
|
+
"type",
|
|
124
|
+
"seq",
|
|
125
|
+
"at",
|
|
126
|
+
"personId"
|
|
127
|
+
],
|
|
128
|
+
"additionalProperties": false
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"type": "object",
|
|
132
|
+
"properties": {
|
|
133
|
+
"type": {
|
|
134
|
+
"type": "string",
|
|
135
|
+
"const": "title"
|
|
136
|
+
},
|
|
137
|
+
"seq": {
|
|
138
|
+
"type": "integer",
|
|
139
|
+
"minimum": 0,
|
|
140
|
+
"maximum": 9007199254740991
|
|
141
|
+
},
|
|
142
|
+
"at": {
|
|
143
|
+
"type": "string"
|
|
144
|
+
},
|
|
145
|
+
"title": {
|
|
146
|
+
"type": "string"
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"required": [
|
|
150
|
+
"type",
|
|
151
|
+
"seq",
|
|
152
|
+
"at",
|
|
153
|
+
"title"
|
|
154
|
+
],
|
|
155
|
+
"additionalProperties": false
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"type": "object",
|
|
159
|
+
"properties": {
|
|
160
|
+
"type": {
|
|
161
|
+
"type": "string",
|
|
162
|
+
"const": "end"
|
|
163
|
+
},
|
|
164
|
+
"seq": {
|
|
165
|
+
"type": "integer",
|
|
166
|
+
"minimum": 0,
|
|
167
|
+
"maximum": 9007199254740991
|
|
168
|
+
},
|
|
169
|
+
"at": {
|
|
170
|
+
"type": "string"
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
"required": [
|
|
174
|
+
"type",
|
|
175
|
+
"seq",
|
|
176
|
+
"at"
|
|
177
|
+
],
|
|
178
|
+
"additionalProperties": false
|
|
179
|
+
}
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
"required": [
|
|
185
|
+
"events"
|
|
186
|
+
],
|
|
187
|
+
"additionalProperties": false
|
|
188
|
+
},
|
|
189
|
+
"PersonCreate": {
|
|
190
|
+
"type": "object",
|
|
191
|
+
"properties": {
|
|
192
|
+
"display_name": {
|
|
193
|
+
"type": "string"
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
"additionalProperties": false
|
|
197
|
+
},
|
|
198
|
+
"PersonUpdate": {
|
|
199
|
+
"type": "object",
|
|
200
|
+
"properties": {
|
|
201
|
+
"display_name": {
|
|
202
|
+
"anyOf": [
|
|
203
|
+
{
|
|
204
|
+
"type": "string"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"type": "null"
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
"additionalProperties": false
|
|
213
|
+
},
|
|
214
|
+
"SearchRequest": {
|
|
215
|
+
"type": "object",
|
|
216
|
+
"properties": {
|
|
217
|
+
"query": {
|
|
218
|
+
"anyOf": [
|
|
219
|
+
{
|
|
220
|
+
"type": "object",
|
|
221
|
+
"properties": {
|
|
222
|
+
"sessionId": {
|
|
223
|
+
"type": "string",
|
|
224
|
+
"minLength": 1
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
"required": [
|
|
228
|
+
"sessionId"
|
|
229
|
+
],
|
|
230
|
+
"additionalProperties": false
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"type": "object",
|
|
234
|
+
"properties": {
|
|
235
|
+
"session": {
|
|
236
|
+
"type": "object",
|
|
237
|
+
"properties": {
|
|
238
|
+
"steps": {
|
|
239
|
+
"type": "array",
|
|
240
|
+
"items": {
|
|
241
|
+
"type": "object",
|
|
242
|
+
"properties": {
|
|
243
|
+
"tool": {
|
|
244
|
+
"type": "string"
|
|
245
|
+
},
|
|
246
|
+
"resources": {
|
|
247
|
+
"type": "array",
|
|
248
|
+
"items": {
|
|
249
|
+
"type": "string"
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
"required": [
|
|
254
|
+
"tool",
|
|
255
|
+
"resources"
|
|
256
|
+
],
|
|
257
|
+
"additionalProperties": false
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
"participants": {
|
|
261
|
+
"type": "array",
|
|
262
|
+
"items": {
|
|
263
|
+
"type": "string"
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
"required": [
|
|
268
|
+
"steps"
|
|
269
|
+
],
|
|
270
|
+
"additionalProperties": false
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
"required": [
|
|
274
|
+
"session"
|
|
275
|
+
],
|
|
276
|
+
"additionalProperties": false
|
|
277
|
+
}
|
|
278
|
+
]
|
|
279
|
+
},
|
|
280
|
+
"options": {
|
|
281
|
+
"type": "object",
|
|
282
|
+
"propertyNames": {
|
|
283
|
+
"type": "string"
|
|
284
|
+
},
|
|
285
|
+
"additionalProperties": {}
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
"required": [
|
|
289
|
+
"query"
|
|
290
|
+
],
|
|
291
|
+
"additionalProperties": false
|
|
292
|
+
},
|
|
293
|
+
"CreateWorkspace": {
|
|
294
|
+
"type": "object",
|
|
295
|
+
"properties": {
|
|
296
|
+
"id": {
|
|
297
|
+
"type": "string"
|
|
298
|
+
},
|
|
299
|
+
"name": {
|
|
300
|
+
"type": "string"
|
|
301
|
+
},
|
|
302
|
+
"metadata": {
|
|
303
|
+
"type": "object",
|
|
304
|
+
"propertyNames": {
|
|
305
|
+
"type": "string"
|
|
306
|
+
},
|
|
307
|
+
"additionalProperties": {}
|
|
308
|
+
},
|
|
309
|
+
"issueKey": {
|
|
310
|
+
"type": "boolean"
|
|
311
|
+
},
|
|
312
|
+
"keyName": {
|
|
313
|
+
"type": "string"
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
"additionalProperties": false
|
|
317
|
+
},
|
|
318
|
+
"IssueKey": {
|
|
319
|
+
"type": "object",
|
|
320
|
+
"properties": {
|
|
321
|
+
"name": {
|
|
322
|
+
"type": "string"
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
"additionalProperties": false
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
"paths": {
|
|
330
|
+
"/v1/me": {
|
|
331
|
+
"get": {
|
|
332
|
+
"summary": "Identity probe — the workspace the caller's key resolves to.",
|
|
333
|
+
"responses": {
|
|
334
|
+
"200": {
|
|
335
|
+
"description": "workspace id"
|
|
336
|
+
},
|
|
337
|
+
"401": {
|
|
338
|
+
"description": "unauthorized"
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
"/v1/sessions": {
|
|
344
|
+
"post": {
|
|
345
|
+
"summary": "Create a session.",
|
|
346
|
+
"requestBody": {
|
|
347
|
+
"required": true,
|
|
348
|
+
"content": {
|
|
349
|
+
"application/json": {
|
|
350
|
+
"schema": {
|
|
351
|
+
"$ref": "#/components/schemas/SessionInit"
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
"responses": {
|
|
357
|
+
"200": {
|
|
358
|
+
"description": "created session id"
|
|
359
|
+
},
|
|
360
|
+
"400": {
|
|
361
|
+
"description": "invalid body"
|
|
362
|
+
},
|
|
363
|
+
"401": {
|
|
364
|
+
"description": "unauthorized"
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
},
|
|
368
|
+
"get": {
|
|
369
|
+
"summary": "List recent sessions plus their persons map.",
|
|
370
|
+
"parameters": [
|
|
371
|
+
{
|
|
372
|
+
"name": "limit",
|
|
373
|
+
"in": "query",
|
|
374
|
+
"required": false,
|
|
375
|
+
"schema": {
|
|
376
|
+
"type": "integer",
|
|
377
|
+
"minimum": 1
|
|
378
|
+
},
|
|
379
|
+
"description": "Page size; clamped server-side."
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
"name": "channel",
|
|
383
|
+
"in": "query",
|
|
384
|
+
"required": false,
|
|
385
|
+
"schema": {
|
|
386
|
+
"type": "string"
|
|
387
|
+
},
|
|
388
|
+
"description": "Filter by session channel."
|
|
389
|
+
}
|
|
390
|
+
],
|
|
391
|
+
"responses": {
|
|
392
|
+
"200": {
|
|
393
|
+
"description": "session list envelope"
|
|
394
|
+
},
|
|
395
|
+
"401": {
|
|
396
|
+
"description": "unauthorized"
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
},
|
|
401
|
+
"/v1/sessions/{id}": {
|
|
402
|
+
"get": {
|
|
403
|
+
"summary": "Fetch one session plus its persons map.",
|
|
404
|
+
"parameters": [
|
|
405
|
+
{
|
|
406
|
+
"name": "id",
|
|
407
|
+
"in": "path",
|
|
408
|
+
"required": true,
|
|
409
|
+
"schema": {
|
|
410
|
+
"type": "string"
|
|
411
|
+
},
|
|
412
|
+
"description": "Session id."
|
|
413
|
+
}
|
|
414
|
+
],
|
|
415
|
+
"responses": {
|
|
416
|
+
"200": {
|
|
417
|
+
"description": "session envelope"
|
|
418
|
+
},
|
|
419
|
+
"401": {
|
|
420
|
+
"description": "unauthorized"
|
|
421
|
+
},
|
|
422
|
+
"404": {
|
|
423
|
+
"description": "session not found"
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
},
|
|
428
|
+
"/v1/sessions/{id}/events": {
|
|
429
|
+
"post": {
|
|
430
|
+
"summary": "Append events to a session.",
|
|
431
|
+
"parameters": [
|
|
432
|
+
{
|
|
433
|
+
"name": "id",
|
|
434
|
+
"in": "path",
|
|
435
|
+
"required": true,
|
|
436
|
+
"schema": {
|
|
437
|
+
"type": "string"
|
|
438
|
+
},
|
|
439
|
+
"description": "Session id."
|
|
440
|
+
}
|
|
441
|
+
],
|
|
442
|
+
"requestBody": {
|
|
443
|
+
"required": true,
|
|
444
|
+
"content": {
|
|
445
|
+
"application/json": {
|
|
446
|
+
"schema": {
|
|
447
|
+
"$ref": "#/components/schemas/EventBatch"
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
"responses": {
|
|
453
|
+
"204": {
|
|
454
|
+
"description": "appended"
|
|
455
|
+
},
|
|
456
|
+
"400": {
|
|
457
|
+
"description": "invalid body"
|
|
458
|
+
},
|
|
459
|
+
"401": {
|
|
460
|
+
"description": "unauthorized"
|
|
461
|
+
},
|
|
462
|
+
"404": {
|
|
463
|
+
"description": "session not found"
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
},
|
|
468
|
+
"/v1/search": {
|
|
469
|
+
"post": {
|
|
470
|
+
"summary": "Score the workspace corpus against a query session.",
|
|
471
|
+
"requestBody": {
|
|
472
|
+
"required": true,
|
|
473
|
+
"content": {
|
|
474
|
+
"application/json": {
|
|
475
|
+
"schema": {
|
|
476
|
+
"$ref": "#/components/schemas/SearchRequest"
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
"responses": {
|
|
482
|
+
"200": {
|
|
483
|
+
"description": "scored results plus persons map"
|
|
484
|
+
},
|
|
485
|
+
"400": {
|
|
486
|
+
"description": "invalid body"
|
|
487
|
+
},
|
|
488
|
+
"401": {
|
|
489
|
+
"description": "unauthorized"
|
|
490
|
+
},
|
|
491
|
+
"404": {
|
|
492
|
+
"description": "query session not found"
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
"/v1/persons": {
|
|
498
|
+
"post": {
|
|
499
|
+
"summary": "Create a person (server allocates the id).",
|
|
500
|
+
"requestBody": {
|
|
501
|
+
"required": true,
|
|
502
|
+
"content": {
|
|
503
|
+
"application/json": {
|
|
504
|
+
"schema": {
|
|
505
|
+
"$ref": "#/components/schemas/PersonCreate"
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
},
|
|
510
|
+
"responses": {
|
|
511
|
+
"201": {
|
|
512
|
+
"description": "created person"
|
|
513
|
+
},
|
|
514
|
+
"400": {
|
|
515
|
+
"description": "invalid body"
|
|
516
|
+
},
|
|
517
|
+
"401": {
|
|
518
|
+
"description": "unauthorized"
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
},
|
|
522
|
+
"get": {
|
|
523
|
+
"summary": "List or free-text search persons.",
|
|
524
|
+
"parameters": [
|
|
525
|
+
{
|
|
526
|
+
"name": "limit",
|
|
527
|
+
"in": "query",
|
|
528
|
+
"required": false,
|
|
529
|
+
"schema": {
|
|
530
|
+
"type": "integer",
|
|
531
|
+
"minimum": 1
|
|
532
|
+
},
|
|
533
|
+
"description": "Page size; clamped server-side."
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
"name": "q",
|
|
537
|
+
"in": "query",
|
|
538
|
+
"required": false,
|
|
539
|
+
"schema": {
|
|
540
|
+
"type": "string"
|
|
541
|
+
},
|
|
542
|
+
"description": "Free-text query over id + display_name."
|
|
543
|
+
}
|
|
544
|
+
],
|
|
545
|
+
"responses": {
|
|
546
|
+
"200": {
|
|
547
|
+
"description": "person list"
|
|
548
|
+
},
|
|
549
|
+
"401": {
|
|
550
|
+
"description": "unauthorized"
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
},
|
|
555
|
+
"/v1/persons/{id}": {
|
|
556
|
+
"put": {
|
|
557
|
+
"summary": "Upsert a person at a caller-supplied id.",
|
|
558
|
+
"parameters": [
|
|
559
|
+
{
|
|
560
|
+
"name": "id",
|
|
561
|
+
"in": "path",
|
|
562
|
+
"required": true,
|
|
563
|
+
"schema": {
|
|
564
|
+
"type": "string"
|
|
565
|
+
},
|
|
566
|
+
"description": "Person id."
|
|
567
|
+
}
|
|
568
|
+
],
|
|
569
|
+
"requestBody": {
|
|
570
|
+
"required": true,
|
|
571
|
+
"content": {
|
|
572
|
+
"application/json": {
|
|
573
|
+
"schema": {
|
|
574
|
+
"$ref": "#/components/schemas/PersonCreate"
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
},
|
|
579
|
+
"responses": {
|
|
580
|
+
"200": {
|
|
581
|
+
"description": "upserted person"
|
|
582
|
+
},
|
|
583
|
+
"400": {
|
|
584
|
+
"description": "invalid body"
|
|
585
|
+
},
|
|
586
|
+
"401": {
|
|
587
|
+
"description": "unauthorized"
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
},
|
|
591
|
+
"patch": {
|
|
592
|
+
"summary": "Patch a person's profile fields.",
|
|
593
|
+
"parameters": [
|
|
594
|
+
{
|
|
595
|
+
"name": "id",
|
|
596
|
+
"in": "path",
|
|
597
|
+
"required": true,
|
|
598
|
+
"schema": {
|
|
599
|
+
"type": "string"
|
|
600
|
+
},
|
|
601
|
+
"description": "Person id."
|
|
602
|
+
}
|
|
603
|
+
],
|
|
604
|
+
"requestBody": {
|
|
605
|
+
"required": true,
|
|
606
|
+
"content": {
|
|
607
|
+
"application/json": {
|
|
608
|
+
"schema": {
|
|
609
|
+
"$ref": "#/components/schemas/PersonUpdate"
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
},
|
|
614
|
+
"responses": {
|
|
615
|
+
"200": {
|
|
616
|
+
"description": "updated person"
|
|
617
|
+
},
|
|
618
|
+
"400": {
|
|
619
|
+
"description": "invalid body"
|
|
620
|
+
},
|
|
621
|
+
"401": {
|
|
622
|
+
"description": "unauthorized"
|
|
623
|
+
},
|
|
624
|
+
"404": {
|
|
625
|
+
"description": "person not found"
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
},
|
|
629
|
+
"get": {
|
|
630
|
+
"summary": "Fetch one person.",
|
|
631
|
+
"parameters": [
|
|
632
|
+
{
|
|
633
|
+
"name": "id",
|
|
634
|
+
"in": "path",
|
|
635
|
+
"required": true,
|
|
636
|
+
"schema": {
|
|
637
|
+
"type": "string"
|
|
638
|
+
},
|
|
639
|
+
"description": "Person id."
|
|
640
|
+
}
|
|
641
|
+
],
|
|
642
|
+
"responses": {
|
|
643
|
+
"200": {
|
|
644
|
+
"description": "person"
|
|
645
|
+
},
|
|
646
|
+
"401": {
|
|
647
|
+
"description": "unauthorized"
|
|
648
|
+
},
|
|
649
|
+
"404": {
|
|
650
|
+
"description": "person not found"
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
},
|
|
655
|
+
"/v1/persons/{id}/sessions": {
|
|
656
|
+
"get": {
|
|
657
|
+
"summary": "Sessions this person participates in (or can view).",
|
|
658
|
+
"parameters": [
|
|
659
|
+
{
|
|
660
|
+
"name": "id",
|
|
661
|
+
"in": "path",
|
|
662
|
+
"required": true,
|
|
663
|
+
"schema": {
|
|
664
|
+
"type": "string"
|
|
665
|
+
},
|
|
666
|
+
"description": "Person id."
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
"name": "limit",
|
|
670
|
+
"in": "query",
|
|
671
|
+
"required": false,
|
|
672
|
+
"schema": {
|
|
673
|
+
"type": "integer",
|
|
674
|
+
"minimum": 1
|
|
675
|
+
},
|
|
676
|
+
"description": "Page size; clamped server-side."
|
|
677
|
+
},
|
|
678
|
+
{
|
|
679
|
+
"name": "channel",
|
|
680
|
+
"in": "query",
|
|
681
|
+
"required": false,
|
|
682
|
+
"schema": {
|
|
683
|
+
"type": "string"
|
|
684
|
+
},
|
|
685
|
+
"description": "Filter by session channel."
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
"name": "scope",
|
|
689
|
+
"in": "query",
|
|
690
|
+
"required": false,
|
|
691
|
+
"schema": {
|
|
692
|
+
"type": "string",
|
|
693
|
+
"enum": [
|
|
694
|
+
"participant",
|
|
695
|
+
"viewable"
|
|
696
|
+
]
|
|
697
|
+
},
|
|
698
|
+
"description": "`participant` (default) or `viewable`."
|
|
699
|
+
}
|
|
700
|
+
],
|
|
701
|
+
"responses": {
|
|
702
|
+
"200": {
|
|
703
|
+
"description": "session list envelope"
|
|
704
|
+
},
|
|
705
|
+
"401": {
|
|
706
|
+
"description": "unauthorized"
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
},
|
|
711
|
+
"/admin/v1/workspaces": {
|
|
712
|
+
"post": {
|
|
713
|
+
"summary": "Create a workspace (and, by default, an initial key).",
|
|
714
|
+
"security": [
|
|
715
|
+
{
|
|
716
|
+
"adminToken": []
|
|
717
|
+
}
|
|
718
|
+
],
|
|
719
|
+
"requestBody": {
|
|
720
|
+
"required": true,
|
|
721
|
+
"content": {
|
|
722
|
+
"application/json": {
|
|
723
|
+
"schema": {
|
|
724
|
+
"$ref": "#/components/schemas/CreateWorkspace"
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
},
|
|
729
|
+
"responses": {
|
|
730
|
+
"200": {
|
|
731
|
+
"description": "workspace, plus key unless issueKey=false"
|
|
732
|
+
},
|
|
733
|
+
"400": {
|
|
734
|
+
"description": "invalid body or workspace id"
|
|
735
|
+
},
|
|
736
|
+
"401": {
|
|
737
|
+
"description": "unauthorized"
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
},
|
|
741
|
+
"get": {
|
|
742
|
+
"summary": "List all workspaces.",
|
|
743
|
+
"security": [
|
|
744
|
+
{
|
|
745
|
+
"adminToken": []
|
|
746
|
+
}
|
|
747
|
+
],
|
|
748
|
+
"responses": {
|
|
749
|
+
"200": {
|
|
750
|
+
"description": "workspace list"
|
|
751
|
+
},
|
|
752
|
+
"401": {
|
|
753
|
+
"description": "unauthorized"
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
},
|
|
758
|
+
"/admin/v1/workspaces/{id}": {
|
|
759
|
+
"get": {
|
|
760
|
+
"summary": "Fetch one workspace.",
|
|
761
|
+
"security": [
|
|
762
|
+
{
|
|
763
|
+
"adminToken": []
|
|
764
|
+
}
|
|
765
|
+
],
|
|
766
|
+
"parameters": [
|
|
767
|
+
{
|
|
768
|
+
"name": "id",
|
|
769
|
+
"in": "path",
|
|
770
|
+
"required": true,
|
|
771
|
+
"schema": {
|
|
772
|
+
"type": "string"
|
|
773
|
+
},
|
|
774
|
+
"description": "Workspace id."
|
|
775
|
+
}
|
|
776
|
+
],
|
|
777
|
+
"responses": {
|
|
778
|
+
"200": {
|
|
779
|
+
"description": "workspace"
|
|
780
|
+
},
|
|
781
|
+
"401": {
|
|
782
|
+
"description": "unauthorized"
|
|
783
|
+
},
|
|
784
|
+
"404": {
|
|
785
|
+
"description": "workspace not found"
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
},
|
|
789
|
+
"delete": {
|
|
790
|
+
"summary": "Delete a workspace (cascades to keys, sessions, events).",
|
|
791
|
+
"security": [
|
|
792
|
+
{
|
|
793
|
+
"adminToken": []
|
|
794
|
+
}
|
|
795
|
+
],
|
|
796
|
+
"parameters": [
|
|
797
|
+
{
|
|
798
|
+
"name": "id",
|
|
799
|
+
"in": "path",
|
|
800
|
+
"required": true,
|
|
801
|
+
"schema": {
|
|
802
|
+
"type": "string"
|
|
803
|
+
},
|
|
804
|
+
"description": "Workspace id."
|
|
805
|
+
}
|
|
806
|
+
],
|
|
807
|
+
"responses": {
|
|
808
|
+
"204": {
|
|
809
|
+
"description": "deleted"
|
|
810
|
+
},
|
|
811
|
+
"401": {
|
|
812
|
+
"description": "unauthorized"
|
|
813
|
+
},
|
|
814
|
+
"404": {
|
|
815
|
+
"description": "workspace not found"
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
},
|
|
820
|
+
"/admin/v1/workspaces/{id}/keys": {
|
|
821
|
+
"post": {
|
|
822
|
+
"summary": "Issue a new API key for a workspace.",
|
|
823
|
+
"security": [
|
|
824
|
+
{
|
|
825
|
+
"adminToken": []
|
|
826
|
+
}
|
|
827
|
+
],
|
|
828
|
+
"parameters": [
|
|
829
|
+
{
|
|
830
|
+
"name": "id",
|
|
831
|
+
"in": "path",
|
|
832
|
+
"required": true,
|
|
833
|
+
"schema": {
|
|
834
|
+
"type": "string"
|
|
835
|
+
},
|
|
836
|
+
"description": "Workspace id."
|
|
837
|
+
}
|
|
838
|
+
],
|
|
839
|
+
"requestBody": {
|
|
840
|
+
"required": false,
|
|
841
|
+
"content": {
|
|
842
|
+
"application/json": {
|
|
843
|
+
"schema": {
|
|
844
|
+
"$ref": "#/components/schemas/IssueKey"
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
},
|
|
849
|
+
"responses": {
|
|
850
|
+
"200": {
|
|
851
|
+
"description": "issued key (raw key returned once)"
|
|
852
|
+
},
|
|
853
|
+
"400": {
|
|
854
|
+
"description": "invalid body"
|
|
855
|
+
},
|
|
856
|
+
"401": {
|
|
857
|
+
"description": "unauthorized"
|
|
858
|
+
},
|
|
859
|
+
"404": {
|
|
860
|
+
"description": "workspace not found"
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
},
|
|
864
|
+
"get": {
|
|
865
|
+
"summary": "List a workspace's API keys (hashes only).",
|
|
866
|
+
"security": [
|
|
867
|
+
{
|
|
868
|
+
"adminToken": []
|
|
869
|
+
}
|
|
870
|
+
],
|
|
871
|
+
"parameters": [
|
|
872
|
+
{
|
|
873
|
+
"name": "id",
|
|
874
|
+
"in": "path",
|
|
875
|
+
"required": true,
|
|
876
|
+
"schema": {
|
|
877
|
+
"type": "string"
|
|
878
|
+
},
|
|
879
|
+
"description": "Workspace id."
|
|
880
|
+
}
|
|
881
|
+
],
|
|
882
|
+
"responses": {
|
|
883
|
+
"200": {
|
|
884
|
+
"description": "key list"
|
|
885
|
+
},
|
|
886
|
+
"401": {
|
|
887
|
+
"description": "unauthorized"
|
|
888
|
+
},
|
|
889
|
+
"404": {
|
|
890
|
+
"description": "workspace not found"
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
},
|
|
895
|
+
"/admin/v1/workspaces/{id}/keys/{keyId}": {
|
|
896
|
+
"delete": {
|
|
897
|
+
"summary": "Revoke an API key.",
|
|
898
|
+
"security": [
|
|
899
|
+
{
|
|
900
|
+
"adminToken": []
|
|
901
|
+
}
|
|
902
|
+
],
|
|
903
|
+
"parameters": [
|
|
904
|
+
{
|
|
905
|
+
"name": "id",
|
|
906
|
+
"in": "path",
|
|
907
|
+
"required": true,
|
|
908
|
+
"schema": {
|
|
909
|
+
"type": "string"
|
|
910
|
+
},
|
|
911
|
+
"description": "Workspace id."
|
|
912
|
+
},
|
|
913
|
+
{
|
|
914
|
+
"name": "keyId",
|
|
915
|
+
"in": "path",
|
|
916
|
+
"required": true,
|
|
917
|
+
"schema": {
|
|
918
|
+
"type": "string"
|
|
919
|
+
},
|
|
920
|
+
"description": "Key id."
|
|
921
|
+
}
|
|
922
|
+
],
|
|
923
|
+
"responses": {
|
|
924
|
+
"204": {
|
|
925
|
+
"description": "revoked (idempotent)"
|
|
926
|
+
},
|
|
927
|
+
"401": {
|
|
928
|
+
"description": "unauthorized"
|
|
929
|
+
},
|
|
930
|
+
"404": {
|
|
931
|
+
"description": "key not found"
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hexis-ai/engram-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Engram server: ingest agent session events, persist via a pluggable adapter, expose search.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"engram",
|
|
@@ -37,13 +37,15 @@
|
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
39
|
"files": [
|
|
40
|
-
"dist"
|
|
40
|
+
"dist",
|
|
41
|
+
"openapi.json"
|
|
41
42
|
],
|
|
42
43
|
"scripts": {
|
|
43
44
|
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
44
45
|
"pack": "bun run build && bun pm pack",
|
|
45
46
|
"test": "bun test",
|
|
46
47
|
"type-check": "tsc --noEmit",
|
|
48
|
+
"gen:openapi": "bun run scripts/gen-openapi.ts",
|
|
47
49
|
"dev": "bun --hot src/dev.ts"
|
|
48
50
|
},
|
|
49
51
|
"dependencies": {
|