@amodalai/runtime 0.2.0 → 0.2.1
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/src/__fixtures__/README.md +4 -0
- package/dist/src/__fixtures__/e2e.test.d.ts +6 -0
- package/dist/src/__fixtures__/e2e.test.js +211 -0
- package/dist/src/__fixtures__/e2e.test.js.map +1 -0
- package/dist/src/__fixtures__/smoke-agent/automations/delivery-callback-test.json +9 -0
- package/dist/src/__fixtures__/smoke-agent/connections/mock-mcp/spec.json +1 -1
- package/dist/src/__fixtures__/smoke.test.js +715 -29
- package/dist/src/__fixtures__/smoke.test.js.map +1 -1
- package/dist/src/__fixtures__/test-env.d.ts +27 -0
- package/dist/src/__fixtures__/test-env.js +64 -0
- package/dist/src/__fixtures__/test-env.js.map +1 -0
- package/dist/src/__fixtures__/test-helpers.d.ts +30 -0
- package/dist/src/__fixtures__/test-helpers.js +120 -0
- package/dist/src/__fixtures__/test-helpers.js.map +1 -0
- package/dist/src/agent/agent-types.d.ts +22 -0
- package/dist/src/agent/agent-types.js.map +1 -1
- package/dist/src/agent/automation-bridge.d.ts +9 -0
- package/dist/src/agent/automation-bridge.js +26 -0
- package/dist/src/agent/automation-bridge.js.map +1 -1
- package/dist/src/agent/automation-bridge.test.js +63 -0
- package/dist/src/agent/automation-bridge.test.js.map +1 -1
- package/dist/src/agent/local-server.d.ts +0 -7
- package/dist/src/agent/local-server.js +230 -86
- package/dist/src/agent/local-server.js.map +1 -1
- package/dist/src/agent/local-server.test.js +14 -8
- package/dist/src/agent/local-server.test.js.map +1 -1
- package/dist/src/agent/loop-types.d.ts +81 -2
- package/dist/src/agent/loop-types.js +4 -0
- package/dist/src/agent/loop-types.js.map +1 -1
- package/dist/src/agent/loop.js +16 -3
- package/dist/src/agent/loop.js.map +1 -1
- package/dist/src/agent/loop.test.js +572 -8
- package/dist/src/agent/loop.test.js.map +1 -1
- package/dist/src/agent/proactive/delivery-router.d.ts +68 -0
- package/dist/src/agent/proactive/delivery-router.js +337 -0
- package/dist/src/agent/proactive/delivery-router.js.map +1 -0
- package/dist/src/agent/proactive/delivery-router.test.d.ts +6 -0
- package/dist/src/agent/proactive/delivery-router.test.js +455 -0
- package/dist/src/agent/proactive/delivery-router.test.js.map +1 -0
- package/dist/src/agent/proactive/proactive-runner.d.ts +23 -1
- package/dist/src/agent/proactive/proactive-runner.js +42 -10
- package/dist/src/agent/proactive/proactive-runner.js.map +1 -1
- package/dist/src/agent/proactive/proactive-runner.test.js +0 -2
- package/dist/src/agent/proactive/proactive-runner.test.js.map +1 -1
- package/dist/src/agent/routes/admin-chat-abort.test.d.ts +6 -0
- package/dist/src/agent/routes/admin-chat-abort.test.js +206 -0
- package/dist/src/agent/routes/admin-chat-abort.test.js.map +1 -0
- package/dist/src/agent/routes/admin-chat.js +0 -2
- package/dist/src/agent/routes/admin-chat.js.map +1 -1
- package/dist/src/agent/routes/task.test.js +0 -2
- package/dist/src/agent/routes/task.test.js.map +1 -1
- package/dist/src/agent/snapshot-server.js +0 -2
- package/dist/src/agent/snapshot-server.js.map +1 -1
- package/dist/src/agent/states/compacting.js +5 -3
- package/dist/src/agent/states/compacting.js.map +1 -1
- package/dist/src/agent/states/confirming.js +3 -0
- package/dist/src/agent/states/confirming.js.map +1 -1
- package/dist/src/agent/states/dispatching.js +45 -1
- package/dist/src/agent/states/dispatching.js.map +1 -1
- package/dist/src/agent/states/executing.js +225 -81
- package/dist/src/agent/states/executing.js.map +1 -1
- package/dist/src/agent/states/streaming.js +14 -0
- package/dist/src/agent/states/streaming.js.map +1 -1
- package/dist/src/agent/states/thinking.d.ts +1 -1
- package/dist/src/agent/states/thinking.js +246 -29
- package/dist/src/agent/states/thinking.js.map +1 -1
- package/dist/src/agent/token-estimate.d.ts +20 -6
- package/dist/src/agent/token-estimate.js +24 -3
- package/dist/src/agent/token-estimate.js.map +1 -1
- package/dist/src/agent/token-estimate.test.d.ts +6 -0
- package/dist/src/agent/token-estimate.test.js +44 -0
- package/dist/src/agent/token-estimate.test.js.map +1 -0
- package/dist/src/api/create-agent.js +0 -3
- package/dist/src/api/create-agent.js.map +1 -1
- package/dist/src/api/types.d.ts +0 -2
- package/dist/src/env-ref.d.ts +13 -0
- package/dist/src/env-ref.js +31 -0
- package/dist/src/env-ref.js.map +1 -0
- package/dist/src/env-ref.test.d.ts +6 -0
- package/dist/src/env-ref.test.js +34 -0
- package/dist/src/env-ref.test.js.map +1 -0
- package/dist/src/errors.d.ts +15 -0
- package/dist/src/errors.js +22 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/errors.test.js +2 -2
- package/dist/src/errors.test.js.map +1 -1
- package/dist/src/events/event-bus.d.ts +54 -0
- package/dist/src/events/event-bus.js +84 -0
- package/dist/src/events/event-bus.js.map +1 -0
- package/dist/src/events/event-bus.test.d.ts +6 -0
- package/dist/src/events/event-bus.test.js +112 -0
- package/dist/src/events/event-bus.test.js.map +1 -0
- package/dist/src/events/events-route.d.ts +36 -0
- package/dist/src/events/events-route.js +80 -0
- package/dist/src/events/events-route.js.map +1 -0
- package/dist/src/events/events-route.test.d.ts +6 -0
- package/dist/src/events/events-route.test.js +134 -0
- package/dist/src/events/events-route.test.js.map +1 -0
- package/dist/src/events/store-event-wrapper.d.ts +19 -0
- package/dist/src/events/store-event-wrapper.js +57 -0
- package/dist/src/events/store-event-wrapper.js.map +1 -0
- package/dist/src/events/store-event-wrapper.test.d.ts +6 -0
- package/dist/src/events/store-event-wrapper.test.js +91 -0
- package/dist/src/events/store-event-wrapper.test.js.map +1 -0
- package/dist/src/middleware/auth.d.ts +0 -2
- package/dist/src/middleware/auth.js.map +1 -1
- package/dist/src/providers/search-provider.d.ts +64 -0
- package/dist/src/providers/search-provider.js +174 -0
- package/dist/src/providers/search-provider.js.map +1 -0
- package/dist/src/providers/types.d.ts +8 -0
- package/dist/src/routes/ai-stream.d.ts +15 -0
- package/dist/src/routes/ai-stream.js +9 -0
- package/dist/src/routes/ai-stream.js.map +1 -1
- package/dist/src/routes/chat-stream.d.ts +6 -0
- package/dist/src/routes/chat-stream.js +2 -0
- package/dist/src/routes/chat-stream.js.map +1 -1
- package/dist/src/routes/chat.d.ts +6 -0
- package/dist/src/routes/chat.js +2 -0
- package/dist/src/routes/chat.js.map +1 -1
- package/dist/src/routes/session-resolver.d.ts +5 -0
- package/dist/src/routes/session-resolver.js +1 -15
- package/dist/src/routes/session-resolver.js.map +1 -1
- package/dist/src/routes/session-resolver.test.js +7 -6
- package/dist/src/routes/session-resolver.test.js.map +1 -1
- package/dist/src/server.d.ts +6 -0
- package/dist/src/server.js +2 -0
- package/dist/src/server.js.map +1 -1
- package/dist/src/session/drizzle-session-store.d.ts +56 -0
- package/dist/src/session/drizzle-session-store.js +203 -0
- package/dist/src/session/drizzle-session-store.js.map +1 -0
- package/dist/src/session/manager.d.ts +6 -3
- package/dist/src/session/manager.js +46 -16
- package/dist/src/session/manager.js.map +1 -1
- package/dist/src/session/manager.test.js +12 -18
- package/dist/src/session/manager.test.js.map +1 -1
- package/dist/src/session/pglite-session-store.d.ts +23 -0
- package/dist/src/session/pglite-session-store.js +70 -0
- package/dist/src/session/pglite-session-store.js.map +1 -0
- package/dist/src/session/postgres-session-store.d.ts +44 -0
- package/dist/src/session/postgres-session-store.js +138 -0
- package/dist/src/session/postgres-session-store.js.map +1 -0
- package/dist/src/session/session-builder.d.ts +0 -2
- package/dist/src/session/session-builder.js +22 -2
- package/dist/src/session/session-builder.js.map +1 -1
- package/dist/src/session/session-builder.test.js +0 -2
- package/dist/src/session/session-builder.test.js.map +1 -1
- package/dist/src/session/session-store-selector.d.ts +49 -0
- package/dist/src/session/session-store-selector.js +60 -0
- package/dist/src/session/session-store-selector.js.map +1 -0
- package/dist/src/session/session-store-selector.test.d.ts +6 -0
- package/dist/src/session/session-store-selector.test.js +79 -0
- package/dist/src/session/session-store-selector.test.js.map +1 -0
- package/dist/src/session/store.d.ts +146 -32
- package/dist/src/session/store.js +126 -138
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/store.test.js +385 -107
- package/dist/src/session/store.test.js.map +1 -1
- package/dist/src/session/tool-context-factory.d.ts +3 -2
- package/dist/src/session/tool-context-factory.js +1 -2
- package/dist/src/session/tool-context-factory.js.map +1 -1
- package/dist/src/session/tool-context-factory.test.js +1 -4
- package/dist/src/session/tool-context-factory.test.js.map +1 -1
- package/dist/src/session/types.d.ts +13 -6
- package/dist/src/stores/schema.d.ts +0 -34
- package/dist/src/stores/schema.js +6 -4
- package/dist/src/stores/schema.js.map +1 -1
- package/dist/src/tools/admin-file-tools.d.ts +29 -0
- package/dist/src/tools/admin-file-tools.js +525 -11
- package/dist/src/tools/admin-file-tools.js.map +1 -1
- package/dist/src/tools/admin-file-tools.test.js +373 -4
- package/dist/src/tools/admin-file-tools.test.js.map +1 -1
- package/dist/src/tools/custom-tool-adapter.test.js +0 -1
- package/dist/src/tools/custom-tool-adapter.test.js.map +1 -1
- package/dist/src/tools/dispatch-tool.d.ts +4 -4
- package/dist/src/tools/fetch-url-tool.d.ts +23 -0
- package/dist/src/tools/fetch-url-tool.js +333 -0
- package/dist/src/tools/fetch-url-tool.js.map +1 -0
- package/dist/src/tools/fetch-url-tool.test.d.ts +6 -0
- package/dist/src/tools/fetch-url-tool.test.js +228 -0
- package/dist/src/tools/fetch-url-tool.test.js.map +1 -0
- package/dist/src/tools/mcp-tool-adapter.test.js +0 -1
- package/dist/src/tools/mcp-tool-adapter.test.js.map +1 -1
- package/dist/src/tools/registry.test.js +0 -1
- package/dist/src/tools/registry.test.js.map +1 -1
- package/dist/src/tools/request-tool.test.js +0 -1
- package/dist/src/tools/request-tool.test.js.map +1 -1
- package/dist/src/tools/store-tools.test.js +0 -1
- package/dist/src/tools/store-tools.test.js.map +1 -1
- package/dist/src/tools/types.d.ts +20 -2
- package/dist/src/tools/web-search-tool.d.ts +31 -0
- package/dist/src/tools/web-search-tool.js +170 -0
- package/dist/src/tools/web-search-tool.js.map +1 -0
- package/dist/src/tools/web-search-tool.test.d.ts +6 -0
- package/dist/src/tools/web-search-tool.test.js +153 -0
- package/dist/src/tools/web-search-tool.test.js.map +1 -0
- package/dist/src/tools/web-tools-shared.d.ts +21 -0
- package/dist/src/tools/web-tools-shared.js +32 -0
- package/dist/src/tools/web-tools-shared.js.map +1 -0
- package/dist/src/types.d.ts +20 -0
- package/dist/src/types.js +13 -0
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +17 -3
- package/dist/src/agent/session-store.d.ts +0 -71
- package/dist/src/agent/session-store.js +0 -151
- package/dist/src/agent/session-store.js.map +0 -1
- package/dist/src/session/admin-file-tools.d.ts +0 -136
- package/dist/src/session/admin-file-tools.js +0 -240
- package/dist/src/session/admin-file-tools.js.map +0 -1
|
@@ -79,6 +79,10 @@ smoke-mcp-server.mjs — MCP stdio server with search/lookup/count tools
|
|
|
79
79
|
|
|
80
80
|
The test `beforeAll` starts the mock REST server and `createLocalServer()` programmatically on port 9900. Tests call `POST /chat` and parse SSE events from the response.
|
|
81
81
|
|
|
82
|
+
## Web tools (`web_search`, `fetch_url`)
|
|
83
|
+
|
|
84
|
+
When `GOOGLE_API_KEY` is set in `.env.test`, `beforeAll` adds a `webTools` block to `amodal.json` so the agent registers the web tools alongside the existing ones. One additional test fires a real `web_search` call through whichever main provider `SMOKE_TARGET` selects — this exercises the cross-provider case (e.g. Anthropic main + Google-backed search). The web-tool test skips automatically when `GOOGLE_API_KEY` is absent.
|
|
85
|
+
|
|
82
86
|
## LLM non-determinism
|
|
83
87
|
|
|
84
88
|
Some tests depend on the model calling specific tools. When the model chooses not to (despite explicit instruction), the test skips gracefully with a console warning rather than failing. This prevents flaky CI from LLM variability while still catching real code bugs.
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* End-to-end tests for the agent loop against real LLM providers.
|
|
8
|
+
* Exercises:
|
|
9
|
+
*
|
|
10
|
+
* - Token budget enforcement — the loop terminates with
|
|
11
|
+
* DoneReason='budget_exceeded' when cumulative tokens hit maxSessionTokens.
|
|
12
|
+
* - Summarizer hook — context eviction invokes summarizeToolResult
|
|
13
|
+
* and the generated summary flows into subsequent prompts.
|
|
14
|
+
*
|
|
15
|
+
* Parameterized over multiple providers. Select which to run via the
|
|
16
|
+
* E2E_TARGETS env var (comma-separated); defaults to `google`
|
|
17
|
+
* (gemini-2.5-flash) as the cheapest base model. Targets missing an
|
|
18
|
+
* API key auto-skip.
|
|
19
|
+
*
|
|
20
|
+
* E2E_TARGETS=google # base (default)
|
|
21
|
+
* E2E_TARGETS=anthropic # single provider
|
|
22
|
+
* E2E_TARGETS=google,anthropic,openai,groq # all
|
|
23
|
+
*/
|
|
24
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
25
|
+
import { z } from 'zod';
|
|
26
|
+
import { StandaloneSessionManager } from '../session/manager.js';
|
|
27
|
+
import { createPGLiteSessionStore } from '../session/pglite-session-store.js';
|
|
28
|
+
import { createProvider } from '../providers/create-provider.js';
|
|
29
|
+
import { createToolRegistry } from '../tools/registry.js';
|
|
30
|
+
import { createLogger } from '../logger.js';
|
|
31
|
+
import { SSEEventType } from '../types.js';
|
|
32
|
+
import { loadTestEnv, defaultTargetName } from './test-env.js';
|
|
33
|
+
// Pull API keys out of <repo-root>/.env.test (gitignored) so targets
|
|
34
|
+
// whose keys are set can run; others auto-skip.
|
|
35
|
+
loadTestEnv();
|
|
36
|
+
const logger = createLogger({ component: 'test:e2e' });
|
|
37
|
+
const TARGETS = {
|
|
38
|
+
google: { provider: 'google', model: 'gemini-2.5-flash', apiKeyEnv: 'GOOGLE_API_KEY' },
|
|
39
|
+
anthropic: { provider: 'anthropic', model: 'claude-haiku-4-5-20251001', apiKeyEnv: 'ANTHROPIC_API_KEY' },
|
|
40
|
+
openai: { provider: 'openai', model: 'gpt-4o-mini', apiKeyEnv: 'OPENAI_API_KEY' },
|
|
41
|
+
groq: { provider: 'groq', model: 'llama-3.3-70b-versatile', apiKeyEnv: 'GROQ_API_KEY' },
|
|
42
|
+
};
|
|
43
|
+
// If E2E_TARGETS is unset, fall through the shared preference chain
|
|
44
|
+
// (google → anthropic → openai → groq) and pick the first target whose
|
|
45
|
+
// API key is configured.
|
|
46
|
+
const selected = (process.env['E2E_TARGETS'] ?? defaultTargetName(TARGETS))
|
|
47
|
+
.split(',')
|
|
48
|
+
.map((s) => s.trim())
|
|
49
|
+
.filter((s) => s.length > 0);
|
|
50
|
+
const activeTargets = selected
|
|
51
|
+
.map((name) => [name, TARGETS[name]])
|
|
52
|
+
.filter((entry) => {
|
|
53
|
+
const [name, cfg] = entry;
|
|
54
|
+
if (!cfg) {
|
|
55
|
+
// eslint-disable-next-line no-console
|
|
56
|
+
console.warn(`[e2e] unknown target "${name}" — skipped. Known: ${Object.keys(TARGETS).join(', ')}`);
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
if (!process.env[cfg.apiKeyEnv]) {
|
|
60
|
+
// eslint-disable-next-line no-console
|
|
61
|
+
console.warn(`[e2e] ${name}: ${cfg.apiKeyEnv} not set — skipped`);
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
return true;
|
|
65
|
+
});
|
|
66
|
+
const allowAll = {
|
|
67
|
+
check: () => ({ allowed: true }),
|
|
68
|
+
};
|
|
69
|
+
/** Echo tool — returns a plain string so the model sees a clear result. */
|
|
70
|
+
function makeEchoTool() {
|
|
71
|
+
return {
|
|
72
|
+
description: 'Echoes back the input value. Use this whenever the user asks you to echo something.',
|
|
73
|
+
parameters: z.object({ value: z.string() }),
|
|
74
|
+
execute: (params) => Promise.resolve(`echoed: ${params.value}`),
|
|
75
|
+
readOnly: true,
|
|
76
|
+
metadata: { category: 'custom' },
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function buildRegistry() {
|
|
80
|
+
const registry = createToolRegistry();
|
|
81
|
+
registry.register('echo_tool', makeEchoTool());
|
|
82
|
+
return registry;
|
|
83
|
+
}
|
|
84
|
+
describe.skipIf(activeTargets.length === 0)('e2e', () => {
|
|
85
|
+
let store;
|
|
86
|
+
let mgr;
|
|
87
|
+
beforeAll(async () => {
|
|
88
|
+
store = await createPGLiteSessionStore({ logger });
|
|
89
|
+
mgr = new StandaloneSessionManager({ logger, store });
|
|
90
|
+
mgr.start();
|
|
91
|
+
});
|
|
92
|
+
afterAll(async () => {
|
|
93
|
+
await mgr.shutdown();
|
|
94
|
+
await store.close();
|
|
95
|
+
});
|
|
96
|
+
describe.each(activeTargets)('[%s]', (_name, target) => {
|
|
97
|
+
it('terminates with budget_exceeded when maxSessionTokens cap is hit', async () => {
|
|
98
|
+
const provider = createProvider({
|
|
99
|
+
provider: target.provider,
|
|
100
|
+
model: target.model,
|
|
101
|
+
apiKey: process.env[target.apiKeyEnv],
|
|
102
|
+
});
|
|
103
|
+
// Tiny budget — any first-turn input+output will blow past this,
|
|
104
|
+
// causing budget_exceeded to fire on the next outer-loop check.
|
|
105
|
+
// Small enough that every provider trips regardless of how terse
|
|
106
|
+
// the model chooses to be.
|
|
107
|
+
const MAX_TOKENS = 200;
|
|
108
|
+
const session = mgr.create({
|
|
109
|
+
provider,
|
|
110
|
+
toolRegistry: buildRegistry(),
|
|
111
|
+
permissionChecker: allowAll,
|
|
112
|
+
systemPrompt: 'You are a terse assistant. Use the echo_tool when asked.',
|
|
113
|
+
maxTurns: 10,
|
|
114
|
+
maxSessionTokens: MAX_TOKENS,
|
|
115
|
+
});
|
|
116
|
+
const events = [];
|
|
117
|
+
for await (const event of mgr.runMessage(session.id, 'Echo these strings one at a time: alpha, bravo, charlie, delta, echo, foxtrot. Use echo_tool for each.', { signal: AbortSignal.timeout(60_000) })) {
|
|
118
|
+
events.push(event);
|
|
119
|
+
}
|
|
120
|
+
const done = events.find((e) => e.type === SSEEventType.Done);
|
|
121
|
+
expect(done).toBeDefined();
|
|
122
|
+
if (done && done.type === SSEEventType.Done) {
|
|
123
|
+
expect(done.reason).toBe('budget_exceeded');
|
|
124
|
+
expect(done.usage?.total_tokens ?? 0).toBeGreaterThanOrEqual(MAX_TOKENS);
|
|
125
|
+
}
|
|
126
|
+
}, 90_000);
|
|
127
|
+
it('invokes summarizeToolResult hook when context is evicted', async () => {
|
|
128
|
+
const provider = createProvider({
|
|
129
|
+
provider: target.provider,
|
|
130
|
+
model: target.model,
|
|
131
|
+
apiKey: process.env[target.apiKeyEnv],
|
|
132
|
+
});
|
|
133
|
+
// Seed 20 tool-result messages so the default clearThreshold=15 fires
|
|
134
|
+
// on the very first turn. Messages are in pairs: an assistant tool-call
|
|
135
|
+
// followed by the tool result, matching the real shape. An initial
|
|
136
|
+
// user message is required to satisfy Anthropic's message-sequence
|
|
137
|
+
// validation (conversations must begin with user).
|
|
138
|
+
const seeded = [
|
|
139
|
+
{ role: 'user', content: 'Please echo some seed values for me.' },
|
|
140
|
+
];
|
|
141
|
+
for (let i = 0; i < 20; i++) {
|
|
142
|
+
seeded.push({
|
|
143
|
+
role: 'assistant',
|
|
144
|
+
content: [{
|
|
145
|
+
type: 'tool-call',
|
|
146
|
+
toolCallId: `c${i}`,
|
|
147
|
+
toolName: 'echo_tool',
|
|
148
|
+
input: { value: `seed-${i}` },
|
|
149
|
+
}],
|
|
150
|
+
});
|
|
151
|
+
seeded.push({
|
|
152
|
+
role: 'tool',
|
|
153
|
+
content: [{
|
|
154
|
+
type: 'tool-result',
|
|
155
|
+
toolCallId: `c${i}`,
|
|
156
|
+
toolName: 'echo_tool',
|
|
157
|
+
output: { type: 'text', value: `echoed: seed-${i} with more text to make this a non-trivial result body` },
|
|
158
|
+
}],
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
const session = mgr.create({
|
|
162
|
+
provider,
|
|
163
|
+
toolRegistry: buildRegistry(),
|
|
164
|
+
permissionChecker: allowAll,
|
|
165
|
+
systemPrompt: 'You are a terse assistant. Answer in one short sentence.',
|
|
166
|
+
maxTurns: 2,
|
|
167
|
+
messages: seeded,
|
|
168
|
+
});
|
|
169
|
+
// Recording summarizer — captures calls to verify hook plumbing.
|
|
170
|
+
const summarizerCalls = [];
|
|
171
|
+
const summarizer = (opts) => {
|
|
172
|
+
summarizerCalls.push({
|
|
173
|
+
toolName: opts.toolName,
|
|
174
|
+
content: opts.content,
|
|
175
|
+
hasSignal: opts.signal instanceof AbortSignal,
|
|
176
|
+
});
|
|
177
|
+
return Promise.resolve('3 items echoed');
|
|
178
|
+
};
|
|
179
|
+
const events = [];
|
|
180
|
+
for await (const event of mgr.runMessage(session.id, 'Briefly say "done".', {
|
|
181
|
+
signal: AbortSignal.timeout(60_000),
|
|
182
|
+
summarizeToolResult: summarizer,
|
|
183
|
+
})) {
|
|
184
|
+
events.push(event);
|
|
185
|
+
}
|
|
186
|
+
// clearThreshold=15, keepRecent=5 → 15 messages should be cleared and
|
|
187
|
+
// the summarizer should be called for each (none are pre-cleared).
|
|
188
|
+
expect(summarizerCalls.length).toBe(15);
|
|
189
|
+
// Every call should have received a real AbortSignal
|
|
190
|
+
for (const call of summarizerCalls) {
|
|
191
|
+
expect(call.hasSignal).toBe(true);
|
|
192
|
+
expect(call.toolName).toBe('echo_tool');
|
|
193
|
+
expect(call.content).toContain('echoed:');
|
|
194
|
+
}
|
|
195
|
+
// The session should have terminated normally (model responded)
|
|
196
|
+
const done = events.find((e) => e.type === SSEEventType.Done);
|
|
197
|
+
expect(done).toBeDefined();
|
|
198
|
+
// Session messages should now contain the summary marker in the cleared positions
|
|
199
|
+
const clearedWithSummary = session.messages.filter((msg) => msg.role === 'tool' &&
|
|
200
|
+
Array.isArray(msg.content) &&
|
|
201
|
+
msg.content.some((part) => 'output' in part &&
|
|
202
|
+
part.output &&
|
|
203
|
+
typeof part.output === 'object' &&
|
|
204
|
+
'value' in part.output &&
|
|
205
|
+
typeof part.output.value === 'string' &&
|
|
206
|
+
part.output.value.includes('3 items echoed')));
|
|
207
|
+
expect(clearedWithSummary.length).toBe(15);
|
|
208
|
+
}, 90_000);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
//# sourceMappingURL=e2e.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e2e.test.js","sourceRoot":"","sources":["../../../src/__fixtures__/e2e.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Delivery Callback Test",
|
|
3
|
+
"trigger": "manual",
|
|
4
|
+
"prompt": "Reply with just this JSON object: {\"status\":\"done\",\"count\":7}",
|
|
5
|
+
"delivery": {
|
|
6
|
+
"targets": [{ "type": "callback" }],
|
|
7
|
+
"template": "Automation {{automation}} finished with count={{count}}"
|
|
8
|
+
}
|
|
9
|
+
}
|