@agentapplicationprotocol/server 0.5.0 → 0.6.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.
|
@@ -54,7 +54,7 @@ const agent = new agent_js_1.Agent("basic-agent", {
|
|
|
54
54
|
});
|
|
55
55
|
const handler = {
|
|
56
56
|
getMeta() {
|
|
57
|
-
return {
|
|
57
|
+
return { agents: [agent.info] };
|
|
58
58
|
},
|
|
59
59
|
createSession(req) {
|
|
60
60
|
const sessionId = `sess_${(0, node_crypto_1.randomUUID)()}`;
|
|
@@ -74,16 +74,21 @@ const handler = {
|
|
|
74
74
|
throw new Error(`Session not found: ${sessionId}`);
|
|
75
75
|
return session.runTurn(req);
|
|
76
76
|
},
|
|
77
|
-
async getSession(sessionId
|
|
77
|
+
async getSession(sessionId) {
|
|
78
|
+
const session = sessions.get(sessionId);
|
|
79
|
+
if (!session)
|
|
80
|
+
throw new Error(`Session not found: ${sessionId}`);
|
|
81
|
+
return session.toSessionResponse();
|
|
82
|
+
},
|
|
83
|
+
async getSessionHistory(sessionId, type) {
|
|
78
84
|
const session = sessions.get(sessionId);
|
|
79
85
|
if (!session)
|
|
80
86
|
throw new Error(`Session not found: ${sessionId}`);
|
|
81
87
|
// history is never compacted, so compacted and full are the same
|
|
82
|
-
|
|
83
|
-
return { ...session.toSessionResponse(), history: historyData };
|
|
88
|
+
return session.history;
|
|
84
89
|
},
|
|
85
90
|
async listSessions() {
|
|
86
|
-
return { sessions: [...sessions.
|
|
91
|
+
return { sessions: [...sessions.values()].map((s) => s.toSessionResponse()) };
|
|
87
92
|
},
|
|
88
93
|
async deleteSession(sessionId) {
|
|
89
94
|
sessions.delete(sessionId);
|
|
@@ -52,7 +52,7 @@ const agent = new agent_js_1.Agent("compact-history-agent", {
|
|
|
52
52
|
});
|
|
53
53
|
const handler = {
|
|
54
54
|
getMeta() {
|
|
55
|
-
return {
|
|
55
|
+
return { agents: [agent.info] };
|
|
56
56
|
},
|
|
57
57
|
createSession(req) {
|
|
58
58
|
const sessionId = `sess_${(0, node_crypto_1.randomUUID)()}`;
|
|
@@ -72,20 +72,20 @@ const handler = {
|
|
|
72
72
|
throw new Error(`Session not found: ${sessionId}`);
|
|
73
73
|
return session.runTurn(req);
|
|
74
74
|
},
|
|
75
|
-
async getSession(sessionId
|
|
75
|
+
async getSession(sessionId) {
|
|
76
76
|
const session = session_js_1.sessions.get(sessionId);
|
|
77
77
|
if (!session)
|
|
78
78
|
throw new Error(`Session not found: ${sessionId}`);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return
|
|
79
|
+
return session.toSessionResponse();
|
|
80
|
+
},
|
|
81
|
+
async getSessionHistory(sessionId, type) {
|
|
82
|
+
const session = session_js_1.sessions.get(sessionId);
|
|
83
|
+
if (!session)
|
|
84
|
+
throw new Error(`Session not found: ${sessionId}`);
|
|
85
|
+
return type === "compacted" ? session.history : session.fullHistory;
|
|
86
86
|
},
|
|
87
87
|
async listSessions() {
|
|
88
|
-
return { sessions: [...session_js_1.sessions.
|
|
88
|
+
return { sessions: [...session_js_1.sessions.values()].map((s) => s.toSessionResponse()) };
|
|
89
89
|
},
|
|
90
90
|
async deleteSession(sessionId) {
|
|
91
91
|
session_js_1.sessions.delete(sessionId);
|
package/dist/src/server.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import { AgentResponse, CreateSessionRequest, CreateSessionResponse, MetaResponse, SessionListResponse, SessionResponse, SessionTurnRequest, SSEEvent } from "@agentapplicationprotocol/core";
|
|
2
|
+
import { AgentResponse, CreateSessionRequest, CreateSessionResponse, HistoryMessage, MetaResponse, SessionListResponse, SessionResponse, SessionTurnRequest, SSEEvent } from "@agentapplicationprotocol/core";
|
|
3
3
|
export interface Handler {
|
|
4
|
-
getMeta(): MetaResponse
|
|
4
|
+
getMeta(): Omit<MetaResponse, "version">;
|
|
5
5
|
listSessions(params: {
|
|
6
6
|
after?: string;
|
|
7
7
|
}): Promise<SessionListResponse>;
|
|
8
|
-
getSession(sessionId: string
|
|
8
|
+
getSession(sessionId: string): Promise<SessionResponse>;
|
|
9
|
+
getSessionHistory(sessionId: string, type: "compacted" | "full"): Promise<HistoryMessage[]>;
|
|
9
10
|
/** The last message in `req.messages` is guaranteed to be a user message. */
|
|
10
11
|
createSession(req: CreateSessionRequest): Promise<CreateSessionResponse> | AsyncIterable<SSEEvent>;
|
|
11
12
|
sendTurn(sessionId: string, req: SessionTurnRequest): Promise<AgentResponse> | AsyncIterable<SSEEvent>;
|
package/dist/src/server.js
CHANGED
|
@@ -41,7 +41,7 @@ function redactSecretOptions(session, agents) {
|
|
|
41
41
|
*/
|
|
42
42
|
function aap(handler) {
|
|
43
43
|
const router = new hono_1.Hono();
|
|
44
|
-
router.get("/meta", (c) => c.json(handler.getMeta()));
|
|
44
|
+
router.get("/meta", (c) => c.json({ version: 2, ...handler.getMeta() }));
|
|
45
45
|
router.put("/session", async (c) => {
|
|
46
46
|
const req = await c.req.json();
|
|
47
47
|
if (req.messages.at(-1)?.role !== "user")
|
|
@@ -61,20 +61,16 @@ function aap(handler) {
|
|
|
61
61
|
return c.json(result);
|
|
62
62
|
});
|
|
63
63
|
router.get("/session/:id", async (c) => {
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
session.history = undefined;
|
|
75
|
-
}
|
|
76
|
-
const meta = handler.getMeta();
|
|
77
|
-
return c.json(redactSecretOptions(session, meta.agents));
|
|
64
|
+
const session = await handler.getSession(c.req.param("id"));
|
|
65
|
+
const { agents } = handler.getMeta();
|
|
66
|
+
return c.json(redactSecretOptions(session, agents));
|
|
67
|
+
});
|
|
68
|
+
router.get("/session/:id/history", async (c) => {
|
|
69
|
+
const typeParam = c.req.query("type");
|
|
70
|
+
if (typeParam !== "compacted" && typeParam !== "full")
|
|
71
|
+
return c.json({ error: 'type must be "compacted" or "full"' }, 400);
|
|
72
|
+
const messages = await handler.getSessionHistory(c.req.param("id"), typeParam);
|
|
73
|
+
return c.json({ history: { [typeParam]: messages } });
|
|
78
74
|
});
|
|
79
75
|
router.get("/sessions", async (c) => {
|
|
80
76
|
const after = c.req.query("after");
|
package/dist/src/server.test.js
CHANGED
|
@@ -5,11 +5,11 @@ const hono_1 = require("hono");
|
|
|
5
5
|
const bearer_auth_1 = require("hono/bearer-auth");
|
|
6
6
|
const cors_1 = require("hono/cors");
|
|
7
7
|
const server_1 = require("./server");
|
|
8
|
-
const meta = { version:
|
|
8
|
+
const meta = { version: 2, agents: [] };
|
|
9
9
|
const session = { sessionId: "s1", agent: { name: "a" } };
|
|
10
10
|
const agentResponse = { stopReason: "end_turn", messages: [] };
|
|
11
11
|
const createSessionResponse = { ...agentResponse, sessionId: "s1" };
|
|
12
|
-
const sessionList = { sessions: [
|
|
12
|
+
const sessionList = { sessions: [session] };
|
|
13
13
|
async function* sseEvents() {
|
|
14
14
|
yield { event: "turn_start" };
|
|
15
15
|
yield { event: "text", text: "hi" };
|
|
@@ -17,9 +17,10 @@ async function* sseEvents() {
|
|
|
17
17
|
}
|
|
18
18
|
function makeHandler(overrides = {}) {
|
|
19
19
|
return {
|
|
20
|
-
getMeta: vitest_1.vi.fn().mockReturnValue(
|
|
20
|
+
getMeta: vitest_1.vi.fn().mockReturnValue({ agents: [] }),
|
|
21
21
|
listSessions: vitest_1.vi.fn().mockResolvedValue(sessionList),
|
|
22
22
|
getSession: vitest_1.vi.fn().mockResolvedValue(session),
|
|
23
|
+
getSessionHistory: vitest_1.vi.fn().mockResolvedValue([]),
|
|
23
24
|
createSession: vitest_1.vi.fn().mockResolvedValue(createSessionResponse),
|
|
24
25
|
sendTurn: vitest_1.vi.fn().mockResolvedValue(agentResponse),
|
|
25
26
|
deleteSession: vitest_1.vi.fn().mockResolvedValue(undefined),
|
|
@@ -57,22 +58,20 @@ function req(method, path, body, headers) {
|
|
|
57
58
|
sessionId: "s1",
|
|
58
59
|
agent: { name: "a", options: { key: "mysecret", model: "gpt-4" } },
|
|
59
60
|
};
|
|
60
|
-
const secretMeta = {
|
|
61
|
-
version: 1,
|
|
62
|
-
agents: [
|
|
63
|
-
{
|
|
64
|
-
name: "a",
|
|
65
|
-
version: "1.0.0",
|
|
66
|
-
options: [
|
|
67
|
-
{ type: "secret", name: "key", default: "" },
|
|
68
|
-
{ type: "text", name: "model", default: "" },
|
|
69
|
-
],
|
|
70
|
-
},
|
|
71
|
-
],
|
|
72
|
-
};
|
|
73
61
|
const app = makeApp(makeHandler({
|
|
74
62
|
getSession: vitest_1.vi.fn().mockResolvedValue(secretSession),
|
|
75
|
-
getMeta: vitest_1.vi.fn().mockReturnValue(
|
|
63
|
+
getMeta: vitest_1.vi.fn().mockReturnValue({
|
|
64
|
+
agents: [
|
|
65
|
+
{
|
|
66
|
+
name: "a",
|
|
67
|
+
version: "1.0.0",
|
|
68
|
+
options: [
|
|
69
|
+
{ type: "secret", name: "key", default: "" },
|
|
70
|
+
{ type: "text", name: "model", default: "" },
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
}),
|
|
76
75
|
}));
|
|
77
76
|
const res = await app.fetch(req("GET", "/session/s1"));
|
|
78
77
|
(0, vitest_1.expect)(res.status).toBe(200);
|
|
@@ -158,7 +157,7 @@ function req(method, path, body, headers) {
|
|
|
158
157
|
};
|
|
159
158
|
const app = makeApp(makeHandler({
|
|
160
159
|
getSession: vitest_1.vi.fn().mockResolvedValue(sessionWithOptions),
|
|
161
|
-
getMeta: vitest_1.vi.fn().mockReturnValue({
|
|
160
|
+
getMeta: vitest_1.vi.fn().mockReturnValue({ agents: [] }),
|
|
162
161
|
}));
|
|
163
162
|
const res = await app.fetch(req("GET", "/session/s1"));
|
|
164
163
|
(0, vitest_1.expect)(await res.json()).toEqual(sessionWithOptions);
|
|
@@ -171,7 +170,6 @@ function req(method, path, body, headers) {
|
|
|
171
170
|
const app = makeApp(makeHandler({
|
|
172
171
|
getSession: vitest_1.vi.fn().mockResolvedValue(sessionWithOptions),
|
|
173
172
|
getMeta: vitest_1.vi.fn().mockReturnValue({
|
|
174
|
-
version: 1,
|
|
175
173
|
agents: [
|
|
176
174
|
{
|
|
177
175
|
name: "a",
|
|
@@ -184,46 +182,27 @@ function req(method, path, body, headers) {
|
|
|
184
182
|
const res = await app.fetch(req("GET", "/session/s1"));
|
|
185
183
|
(0, vitest_1.expect)(await res.json()).toEqual(sessionWithOptions);
|
|
186
184
|
});
|
|
187
|
-
(0, vitest_1.it)("GET /session/:id?
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
...session,
|
|
191
|
-
history: { compacted: [], full: [] },
|
|
192
|
-
}),
|
|
193
|
-
});
|
|
185
|
+
(0, vitest_1.it)("GET /session/:id/history?type=compacted calls getSessionHistory", async () => {
|
|
186
|
+
const messages = [{ role: "user", content: "hi" }];
|
|
187
|
+
const handler = makeHandler({ getSessionHistory: vitest_1.vi.fn().mockResolvedValue(messages) });
|
|
194
188
|
const app = makeApp(handler);
|
|
195
|
-
const res = await app.fetch(req("GET", "/session/s1?
|
|
196
|
-
(0, vitest_1.expect)(
|
|
197
|
-
(0, vitest_1.expect)(
|
|
198
|
-
|
|
199
|
-
(0, vitest_1.it)("GET /session/:id?history=full passes param and strips compacted", async () => {
|
|
200
|
-
const handler = makeHandler({
|
|
201
|
-
getSession: vitest_1.vi.fn().mockResolvedValue({
|
|
202
|
-
...session,
|
|
203
|
-
history: { compacted: [], full: [] },
|
|
204
|
-
}),
|
|
205
|
-
});
|
|
206
|
-
const app = makeApp(handler);
|
|
207
|
-
const res = await app.fetch(req("GET", "/session/s1?history=full"));
|
|
208
|
-
(0, vitest_1.expect)(handler.getSession).toHaveBeenCalledWith("s1", "full");
|
|
209
|
-
(0, vitest_1.expect)(await res.json()).toEqual({ ...session, history: { full: [] } });
|
|
210
|
-
});
|
|
211
|
-
(0, vitest_1.it)("GET /session/:id without ?history passes undefined and strips history from response", async () => {
|
|
212
|
-
const handler = makeHandler({
|
|
213
|
-
getSession: vitest_1.vi.fn().mockResolvedValue({
|
|
214
|
-
...session,
|
|
215
|
-
history: { compacted: [], full: [] },
|
|
216
|
-
}),
|
|
217
|
-
});
|
|
218
|
-
const app = makeApp(handler);
|
|
219
|
-
const res = await app.fetch(req("GET", "/session/s1"));
|
|
220
|
-
(0, vitest_1.expect)(handler.getSession).toHaveBeenCalledWith("s1", undefined);
|
|
221
|
-
(0, vitest_1.expect)(await res.json()).toEqual(session);
|
|
189
|
+
const res = await app.fetch(req("GET", "/session/s1/history?type=compacted"));
|
|
190
|
+
(0, vitest_1.expect)(res.status).toBe(200);
|
|
191
|
+
(0, vitest_1.expect)(handler.getSessionHistory).toHaveBeenCalledWith("s1", "compacted");
|
|
192
|
+
(0, vitest_1.expect)(await res.json()).toEqual({ history: { compacted: messages } });
|
|
222
193
|
});
|
|
223
|
-
(0, vitest_1.it)("GET /session/:id
|
|
224
|
-
const
|
|
194
|
+
(0, vitest_1.it)("GET /session/:id/history?type=full calls getSessionHistory", async () => {
|
|
195
|
+
const messages = [{ role: "user", content: "hi" }];
|
|
196
|
+
const handler = makeHandler({ getSessionHistory: vitest_1.vi.fn().mockResolvedValue(messages) });
|
|
225
197
|
const app = makeApp(handler);
|
|
226
|
-
await app.fetch(req("GET", "/session/s1?
|
|
227
|
-
(0, vitest_1.expect)(
|
|
198
|
+
const res = await app.fetch(req("GET", "/session/s1/history?type=full"));
|
|
199
|
+
(0, vitest_1.expect)(res.status).toBe(200);
|
|
200
|
+
(0, vitest_1.expect)(handler.getSessionHistory).toHaveBeenCalledWith("s1", "full");
|
|
201
|
+
(0, vitest_1.expect)(await res.json()).toEqual({ history: { full: messages } });
|
|
202
|
+
});
|
|
203
|
+
(0, vitest_1.it)("GET /session/:id/history without valid ?type returns 400", async () => {
|
|
204
|
+
const app = makeApp(makeHandler());
|
|
205
|
+
const res = await app.fetch(req("GET", "/session/s1/history"));
|
|
206
|
+
(0, vitest_1.expect)(res.status).toBe(400);
|
|
228
207
|
});
|
|
229
208
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentapplicationprotocol/server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "AAP server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"aap",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"ai": "^6.0.141",
|
|
32
32
|
"hono": "^4.12.8",
|
|
33
33
|
"zod": "^4.3.6",
|
|
34
|
-
"@agentapplicationprotocol/core": "0.
|
|
34
|
+
"@agentapplicationprotocol/core": "0.6.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@ai-sdk/openai": "^3.0.48",
|