name: "TypeScript SDK smoke test"
description: |
Verify the TypeScript SDK (@recursive/sdk) works end-to-end against the
HTTP server:
- Agent.create() opens a session
- agent.send() returns a Run
- run.wait() returns RunResult with all Phase-A fields populated:
status, result (concatenated assistant text), numTurns, durationMs
Requires nodejs to be installed in the e2e container.
The Dockerfile copies sdk/typescript/dist to /sdk/typescript/dist.
sequential: true
setup:
- name: "Kill any leftover server on port 9097"
ignoreError: true
exec:
container: recursive-e2e
command: |
pkill -f 'http --addr 0.0.0.0:9097' 2>/dev/null || true
sleep 1
echo cleaned
- name: "Reset state files"
ignoreError: true
exec:
container: recursive-e2e
command: rm -f /tmp/ts-sdk-result.txt /tmp/ts-sdk-http.log && echo reset
- name: "Start HTTP server on port 9097"
exec:
container: recursive-e2e
command: |
nohup recursive \
--api-base http://aimock:4010/v1 \
--api-key mock-key -m mock-chat \
http --addr 0.0.0.0:9097 \
> /tmp/ts-sdk-http.log 2>&1 &
sleep 2
echo started
- name: "Sanity: GET /health returns ok"
exec:
container: recursive-e2e
command: curl -sf http://localhost:9097/health
expect:
exitCode: 0
output:
contains: "ok"
- name: "Run TypeScript SDK test script, save result to /tmp/ts-sdk-result.txt"
exec:
container: recursive-e2e
command: |
node - <<'JSEOF' > /tmp/ts-sdk-result.txt
const { Agent } = require('/sdk/typescript/dist/index.js');
async function main() {
const agent = await Agent.create({ baseUrl: 'http://localhost:9097', apiKey: 'test' });
try {
const run = await agent.send('sdk-typescript-hello');
const result = await run.wait();
console.log('status=' + result.status);
console.log('has_result=' + (result.result != null));
console.log('num_turns=' + result.numTurns);
console.log('has_duration=' + (result.durationMs != null && result.durationMs >= 0));
} finally {
await agent[Symbol.asyncDispose]();
}
}
main().catch(e => { console.error(e); process.exit(1); });
JSEOF
cat /tmp/ts-sdk-result.txt
expect:
exitCode: 0
output:
contains:
- "status=finished"
- "has_result=true"
cases:
- name: "TypeScript SDK RunResult status is finished"
file:
container: recursive-e2e
path: /tmp/ts-sdk-result.txt
exists: true
contains: "status=finished"
- name: "TypeScript SDK RunResult has non-null result field"
file:
container: recursive-e2e
path: /tmp/ts-sdk-result.txt
exists: true
contains: "has_result=true"
- name: "TypeScript SDK RunResult has numTurns >= 1"
file:
container: recursive-e2e
path: /tmp/ts-sdk-result.txt
exists: true
contains: "num_turns=1"
- name: "TypeScript SDK RunResult has durationMs populated"
file:
container: recursive-e2e
path: /tmp/ts-sdk-result.txt
exists: true
contains: "has_duration=true"
teardown:
- name: "Stop HTTP server on 9097 and clean up"
ignoreError: true
exec:
container: recursive-e2e
command: |
pkill -f 'http --addr 0.0.0.0:9097' 2>/dev/null || true
rm -f /tmp/ts-sdk-result.txt /tmp/ts-sdk-http.log
echo stopped