chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* @vitest-environment node
|
||||
*/
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const { mockRunLocal, mockRunCloud, mockResolveKey } = vi.hoisted(() => ({
|
||||
mockRunLocal: vi.fn(),
|
||||
mockRunCloud: vi.fn(),
|
||||
mockResolveKey: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/executor/handlers/pi/keys', () => ({
|
||||
resolvePiModelKey: mockResolveKey,
|
||||
computePiCost: () => ({ input: 0, output: 0, total: 0 }),
|
||||
}))
|
||||
vi.mock('@/executor/handlers/pi/context', () => ({
|
||||
resolvePiSkills: vi.fn().mockResolvedValue([]),
|
||||
loadPiMemory: vi.fn().mockResolvedValue([]),
|
||||
appendPiMemory: vi.fn().mockResolvedValue(undefined),
|
||||
}))
|
||||
vi.mock('@/executor/handlers/pi/sim-tools', () => ({
|
||||
buildSimToolSpecs: vi.fn().mockResolvedValue([]),
|
||||
}))
|
||||
vi.mock('@/executor/handlers/pi/local-backend', () => ({ runLocalPi: mockRunLocal }))
|
||||
vi.mock('@/executor/handlers/pi/cloud-backend', () => ({ runCloudPi: mockRunCloud }))
|
||||
vi.mock('@/blocks/utils', () => ({
|
||||
parseOptionalNumberInput: (value: unknown) => {
|
||||
const parsed = Number(value)
|
||||
return Number.isFinite(parsed) ? parsed : undefined
|
||||
},
|
||||
}))
|
||||
|
||||
import { PiBlockHandler } from '@/executor/handlers/pi/pi-handler'
|
||||
import type { ExecutionContext, StreamingExecution } from '@/executor/types'
|
||||
import type { SerializedBlock } from '@/serializer/types'
|
||||
|
||||
const block = { id: 'blk', metadata: { id: 'pi' } } as unknown as SerializedBlock
|
||||
|
||||
function ctx(overrides: Partial<ExecutionContext> = {}): ExecutionContext {
|
||||
return {
|
||||
workflowId: 'wf',
|
||||
workspaceId: 'ws',
|
||||
userId: 'user',
|
||||
...overrides,
|
||||
} as ExecutionContext
|
||||
}
|
||||
|
||||
function localInputs(extra: Record<string, unknown> = {}) {
|
||||
return {
|
||||
mode: 'local',
|
||||
task: 'do the thing',
|
||||
model: 'claude',
|
||||
host: 'box.example.com',
|
||||
username: 'deploy',
|
||||
authMethod: 'password',
|
||||
password: 'pw',
|
||||
repoPath: '/srv/repo',
|
||||
...extra,
|
||||
}
|
||||
}
|
||||
|
||||
describe('PiBlockHandler', () => {
|
||||
const handler = new PiBlockHandler()
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
mockResolveKey.mockResolvedValue({ providerId: 'anthropic', apiKey: 'k', isBYOK: true })
|
||||
mockRunLocal.mockResolvedValue({
|
||||
totals: { finalText: 'hi', inputTokens: 1, outputTokens: 2, toolCalls: [] },
|
||||
})
|
||||
mockRunCloud.mockResolvedValue({
|
||||
totals: { finalText: 'done', inputTokens: 0, outputTokens: 0, toolCalls: [] },
|
||||
prUrl: 'https://github.com/o/r/pull/1',
|
||||
branch: 'pi/abc',
|
||||
changedFiles: ['a.ts'],
|
||||
diff: 'diff',
|
||||
})
|
||||
})
|
||||
|
||||
it('canHandle matches the pi block type', () => {
|
||||
expect(handler.canHandle(block)).toBe(true)
|
||||
expect(
|
||||
handler.canHandle({ id: 'x', metadata: { id: 'agent' } } as unknown as SerializedBlock)
|
||||
).toBe(false)
|
||||
})
|
||||
|
||||
it('throws when the task is missing', async () => {
|
||||
await expect(handler.execute(ctx(), block, { mode: 'local', task: '' })).rejects.toThrow(/Task/)
|
||||
})
|
||||
|
||||
it('routes local mode to the local backend with SSH params', async () => {
|
||||
const output = await handler.execute(ctx(), block, localInputs())
|
||||
expect(mockRunLocal).toHaveBeenCalledTimes(1)
|
||||
expect(mockRunCloud).not.toHaveBeenCalled()
|
||||
const params = mockRunLocal.mock.calls[0][0]
|
||||
expect(params.mode).toBe('local')
|
||||
expect(params.ssh.host).toBe('box.example.com')
|
||||
expect(params.repoPath).toBe('/srv/repo')
|
||||
expect((output as Record<string, unknown>).content).toBe('hi')
|
||||
})
|
||||
|
||||
it('routes cloud mode to the cloud backend and surfaces PR output', async () => {
|
||||
const output = (await handler.execute(ctx(), block, {
|
||||
mode: 'cloud',
|
||||
task: 'do it',
|
||||
model: 'claude',
|
||||
owner: 'o',
|
||||
repo: 'r',
|
||||
githubToken: 'ghp',
|
||||
})) as Record<string, unknown>
|
||||
expect(mockRunCloud).toHaveBeenCalledTimes(1)
|
||||
expect(output.prUrl).toBe('https://github.com/o/r/pull/1')
|
||||
expect(output.branch).toBe('pi/abc')
|
||||
})
|
||||
|
||||
it('requires SSH fields in local mode', async () => {
|
||||
await expect(
|
||||
handler.execute(ctx(), block, { mode: 'local', task: 'x', model: 'claude', host: 'h' })
|
||||
).rejects.toThrow(/Local mode requires/)
|
||||
})
|
||||
|
||||
it('requires repo + token in cloud mode', async () => {
|
||||
await expect(
|
||||
handler.execute(ctx(), block, { mode: 'cloud', task: 'x', model: 'claude', owner: 'o' })
|
||||
).rejects.toThrow(/Cloud mode requires/)
|
||||
})
|
||||
|
||||
it('streams text when the block is selected for streaming output', async () => {
|
||||
mockRunLocal.mockImplementation(async (_params, runCtx) => {
|
||||
runCtx.onEvent({ type: 'text', text: 'streamed' })
|
||||
return { totals: { finalText: 'streamed', inputTokens: 0, outputTokens: 0, toolCalls: [] } }
|
||||
})
|
||||
|
||||
const result = (await handler.execute(
|
||||
ctx({ stream: true, selectedOutputs: ['blk'] }),
|
||||
block,
|
||||
localInputs()
|
||||
)) as StreamingExecution
|
||||
|
||||
expect('stream' in result).toBe(true)
|
||||
|
||||
const reader = result.stream.getReader()
|
||||
const decoder = new TextDecoder()
|
||||
let text = ''
|
||||
for (;;) {
|
||||
const { done, value } = await reader.read()
|
||||
if (done) break
|
||||
text += decoder.decode(value)
|
||||
}
|
||||
expect(text).toContain('streamed')
|
||||
expect(result.execution.output.content).toBe('streamed')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user