Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
e8f64b417This file is pinned to the selected release. Download the original to open it in your design tool.
/**
* The daemon's grid RPCs as a desktop drives them — `grid_models_list`, the Model Manager's
* `grid_fleet_models_list` and `agent_retarget` — against a fake relay that records every request it
* receives, and a fake `grid` first on PATH (grid-reads-without-waking issue 02).
*
* The relay is the spy: nothing here recomputes what the daemon sends, it reads what arrived.
*/
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
import { createServer, type IncomingHttpHeaders, type Server } from 'node:http'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { BackendSocket } from './backendSocket.js'
import { env } from './config/env.js'
import { fakeGridAnswers, installFakeGrid, type FakeGrid, type FakeGridPlan } from './lib/__fixtures__/fakeGrid.js'
import { clearGridMcpUrlCache } from './lib/gridMcpUrl.js'
import { resetGridModels, type GridModelsService } from './lib/gridModels.js'
const OWN = 'mine', OWN_ID = 'net-own'
const OVERVIEW = '/relay/v1/grid/overview'
let server: Server, base: string, seen: Array<{ path: string; headers: IncomingHttpHeaders }>
let overview: { status: number; body: unknown }
let root: string, gridHome: string, previousData: string, grid: FakeGrid, service: GridModelsService, clock: number
let socket: BackendSocket, frames: Array<{ type: string; payload: Record<string, unknown> }>
function plan(status: string | null = 'running'): FakeGridPlan {
return {
ls: { stdout: JSON.stringify([{ grid: OWN, id: OWN_ID, type: 'permissioned-public' }]) },
[`info ${OWN}`]: { stdout: JSON.stringify({ grid: OWN, status, grid_url: `${base}/g/${OWN_ID}` }) },
}
}
async function ask(type: string, payload: Record<string, unknown> = {}): Promise<Record<string, unknown>> {
const requestId = `${type}-${frames.length}`
socket.handleLocalFrame('local:grid-reads', { type, payload: { ...payload, requestId } })
await vi.waitFor(() => expect(frames.some((f) => f.payload.requestId === requestId)).toBe(true), { timeout: 10_000 })
return frames.find((f) => f.payload.requestId === requestId)!.payload
}
function expectNoCredential(): void {
for (const request of seen) {
expect(request.headers.authorization).toBeUndefined()
expect(request.headers['x-api-key']).toBeUndefined()
}
}
beforeEach(async () => {
seen = []
overview = { status: 200, body: { nodes: [{ name: 'mac', engine: 'llama.cpp', models: ['small-q4'], online: true }], models: [{ id: 'Small-Q4' }] } }
server = createServer((req, res) => {
seen.push({ path: req.url ?? '', headers: req.headers })
const found = req.url === `/g/${OWN_ID}${OVERVIEW}` ? overview : { status: 404, body: {} }
res.writeHead(found.status, { 'content-type': 'application/json' })
res.end(JSON.stringify(found.body))
})
await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve))
base = `http://127.0.0.1:${(server.address() as { port: number }).port}`
root = mkdtempSync(join(tmpdir(), 'grid-reads-rpc-'))
gridHome = join(root, 'grid-home')
mkdirSync(gridHome, { recursive: true })
vi.stubEnv('GRID_HOME', gridHome)
previousData = env.ADAPTER_DATA_DIR
env.ADAPTER_DATA_DIR = join(root, 'data')
clock = Date.parse('2026-09-24T10:00:00Z')
// Before the socket, which subscribes to the service it finds for its `grid_models_changed` push.
service = resetGridModels({ now: () => clock, dataDir: () => join(root, 'data'), gridHome: () => gridHome, email: () => null })
grid = installFakeGrid(plan())
socket = new BackendSocket('token')
socket.setHarnessGridName(OWN)
frames = []
socket.registerLocalClient('local:grid-reads', { sendFrame: (frame) => { frames.push(frame as typeof frames[number]); return true }, sendBinary: () => true })
})
afterEach(async () => {
await service.settled()
await socket.unregisterLocalClient('local:grid-reads')
await socket.stop()
grid.dispose()
clearGridMcpUrlCache()
env.ADAPTER_DATA_DIR = previousData
vi.unstubAllEnvs()
server.closeAllConnections()
await new Promise<void>((resolve) => server.close(() => resolve()))
rmSync(root, { recursive: true, force: true })
})
describe('grid_models_list', () => {
it('answers in the old shape with the three new fields, and reads the grid with no credential', async () => {
const reply = await ask('grid_models_list')
expect(reply).toMatchObject({ gridName: OWN, models: [{ id: 'Small-Q4', node: 'mac' }] })
expect(reply.grids).toEqual([{
name: OWN, type: 'permissioned-public', own: true, models: [{ id: 'Small-Q4', node: 'mac' }],
state: 'awake', seenAt: new Date(clock).toISOString(), lastKnownAge: 0,
}])
expect(seen.map((r) => r.path)).toEqual([`/g/${OWN_ID}${OVERVIEW}`])
expectNoCredential()
})
it('pushes grid_models_changed when a read it did not wait for changes the list', async () => {
await ask('grid_models_list')
clock += 20_000
overview = { status: 200, body: { nodes: [{ name: 'mac', engine: 'llama.cpp', models: ['small-q4', 'big-q8'] }], models: [] } }
const reply = await ask('grid_models_list')
// Answered at once from the picture; the read it started lands behind it and is pushed.
expect((reply.models as unknown[]).length).toBe(1)
await vi.waitFor(() => expect(frames.some((f) => f.type === 'grid_models_changed')).toBe(true), { timeout: 5_000 })
const pushed = frames.find((f) => f.type === 'grid_models_changed')!.payload
expect(pushed).not.toHaveProperty('requestId')
expect(pushed).toMatchObject({ gridName: OWN, models: [{ id: 'Small-Q4', node: 'mac' }, { id: 'big-q8', node: 'mac' }], supportsModelLaunch: true })
// Two overview reads, and one of provider discovery: `big-q8` had no spelling from any other source.
expect(seen.map((r) => r.path)).toEqual([`/g/${OWN_ID}${OVERVIEW}`, `/g/${OWN_ID}${OVERVIEW}`, `/g/${OWN_ID}/nodes/discover`])
expectNoCredential()
})
})
describe('grid_fleet_models_list (the Model Manager) on a sleeping own grid', () => {
it('is not an inventory error, keeps Start and Pause enabled, and reports a parked engine running', async () => {
grid.replan(plan('asleep'))
overview = { status: 503, body: { detail: 'resting', code: 'grid_asleep' } }
const records = join(gridHome, 'run', 'engines', OWN_ID)
mkdirSync(records, { recursive: true })
writeFileSync(join(records, 'remote.json'), JSON.stringify({
node_id: 'node-1', meta_name: 'mac', pid: process.pid, engines: [{ endpoint_url: null, models: ['Small-Q4.gguf'] }], advertise_as: [],
}))
const reply = await ask('grid_fleet_models_list', { refresh: true })
expect(reply.error).not.toBe('Running models could not be checked. Try again.')
expect(reply.models).toEqual([expect.objectContaining({ id: 'local:Small-Q4.gguf', state: 'running', gridAsleep: true, canStop: true })])
expect(seen.map((r) => r.path)).toEqual([`/g/${OWN_ID}${OVERVIEW}`])
expectNoCredential()
// The owner status is asked once and remembered, not asked on every tick.
await ask('grid_fleet_models_list', { refresh: true })
await ask('grid_fleet_models_list', { refresh: true })
expect(grid.calls().filter((argv) => argv.includes('info'))).toHaveLength(1)
expect(grid.calls().some((argv) => argv.includes('engines'))).toBe(false)
})
})
describe('agent_retarget', () => {
it('reads nothing on its own: the one request is the model lookup of the move a person made', async () => {
const answers = fakeGridAnswers()
// The relay the grid's `info --env` names is this test's, so nothing here can reach a real host.
const relay = `${base}/g/${OWN_ID}/relay/v1`
grid.replan({ ...answers.plan, info: { stdout: `export OPENAI_BASE_URL="${relay}"\nexport OPENAI_API_KEY="${answers.token}"\n` } })
socket.onRetargetAgent = vi.fn(async () => ({ ok: true as const }))
const reply = await ask('agent_retarget', { agentId: 'agent-1', gridModel: 'GLM-4.7-Flash', gridName: answers.gridName })
expect(reply).toMatchObject({ retargeted: true })
// Moving an agent onto a model is a person's act, which may wake the grid (and is meant to: the
// pane is about to use it). What must not happen is any read on the app's own schedule.
expect(seen.map((r) => r.path)).toEqual([`/g/${OWN_ID}/relay/v1/models`])
expect(seen.some((r) => r.path.endsWith('/grid/overview') || r.path.endsWith('/nodes/discover'))).toBe(false)
})
})