chore: fix eslint errors introduced across phases 1-3
This commit is contained in:
@@ -244,7 +244,9 @@ export const inspectUserBoxStatus = async (
|
|||||||
const running = runningField === 'true';
|
const running = runningField === 'true';
|
||||||
return {
|
return {
|
||||||
running,
|
running,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty field means "no image"
|
||||||
image: imageField || null,
|
image: imageField || null,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty field means "not started"
|
||||||
startedAt: running ? startedAtField || null : null,
|
startedAt: running ? startedAtField || null : null,
|
||||||
memoryLimitBytes: Number(memoryField) || null,
|
memoryLimitBytes: Number(memoryField) || null,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ export const parseBoxTokenUsername = (token: string): string | null => {
|
|||||||
const parts = token.split('.');
|
const parts = token.split('.');
|
||||||
if (parts.length !== 4 || parts[1] !== 'box') return null;
|
if (parts.length !== 4 || parts[1] !== 'box') return null;
|
||||||
const username = parts[2];
|
const username = parts[2];
|
||||||
return username ? username : null;
|
if (!username) return null;
|
||||||
|
return username;
|
||||||
};
|
};
|
||||||
|
|
||||||
// User-scoped variant authorizing a terminal connection to a user's box.
|
// User-scoped variant authorizing a terminal connection to a user's box.
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ const createInteractionRequest = async (args: {
|
|||||||
...args,
|
...args,
|
||||||
});
|
});
|
||||||
|
|
||||||
const patchInteractionRequest = async (args: {
|
const _patchInteractionRequest = async (args: {
|
||||||
interactionId: Id<'agentInteractionRequests'>;
|
interactionId: Id<'agentInteractionRequests'>;
|
||||||
status: 'pending' | 'answered' | 'approved' | 'rejected' | 'expired';
|
status: 'pending' | 'answered' | 'approved' | 'rejected' | 'expired';
|
||||||
response?: string;
|
response?: string;
|
||||||
@@ -1179,6 +1179,7 @@ export const replyToInteraction = async (
|
|||||||
externalRequestId: string;
|
externalRequestId: string;
|
||||||
response: string;
|
response: string;
|
||||||
},
|
},
|
||||||
|
// eslint-disable-next-line @typescript-eslint/require-await -- keep async so callers receive a rejected promise
|
||||||
) => {
|
) => {
|
||||||
// Every runtime now runs its CLI non-interactively inside the box, so no
|
// Every runtime now runs its CLI non-interactively inside the box, so no
|
||||||
// runtime emits an interaction request that expects a reply.
|
// runtime emits an interaction request that expects a reply.
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ describe('agent runtime registry', () => {
|
|||||||
test('registerAdapter/getAdapter resolves a registered runtime', () => {
|
test('registerAdapter/getAdapter resolves a registered runtime', () => {
|
||||||
const fake: AgentRuntime = {
|
const fake: AgentRuntime = {
|
||||||
name: 'codex',
|
name: 'codex',
|
||||||
prepareAuth: async () => {},
|
prepareAuth: () => Promise.resolve(),
|
||||||
runTurn: async () => ({}),
|
runTurn: () => Promise.resolve({}),
|
||||||
abort: async () => {},
|
abort: () => Promise.resolve(),
|
||||||
};
|
};
|
||||||
registerAdapter('codex', () => fake);
|
registerAdapter('codex', () => fake);
|
||||||
expect(getAdapter('codex').name).toBe('codex');
|
expect(getAdapter('codex').name).toBe('codex');
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import type { FunctionReturnType } from 'convex/server';
|
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useParams, useRouter } from 'next/navigation';
|
import { useParams, useRouter } from 'next/navigation';
|
||||||
@@ -16,10 +15,7 @@ const AgentWorkspacePage = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const params = useParams<{ spoonId: string; jobId: string }>();
|
const params = useParams<{ spoonId: string; jobId: string }>();
|
||||||
const jobId = params.jobId as Id<'agentJobs'>;
|
const jobId = params.jobId as Id<'agentJobs'>;
|
||||||
const job = useQuery(api.agentJobs.get, { jobId }) as
|
const job = useQuery(api.agentJobs.get, { jobId });
|
||||||
| FunctionReturnType<typeof api.agentJobs.get>
|
|
||||||
| null
|
|
||||||
| undefined;
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (job?.threadId) router.replace(`/threads/${job.threadId}`);
|
if (job?.threadId) router.replace(`/threads/${job.threadId}`);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import type { FunctionReturnType } from 'convex/server';
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useParams, useRouter } from 'next/navigation';
|
import { useParams, useRouter } from 'next/navigation';
|
||||||
@@ -34,10 +33,7 @@ const ThreadDetailPage = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const params = useParams<{ threadId: string }>();
|
const params = useParams<{ threadId: string }>();
|
||||||
const threadId = params.threadId as Id<'threads'>;
|
const threadId = params.threadId as Id<'threads'>;
|
||||||
const details = useQuery(api.threads.get, { threadId }) as
|
const details = useQuery(api.threads.get, { threadId });
|
||||||
| FunctionReturnType<typeof api.threads.get>
|
|
||||||
| null
|
|
||||||
| undefined;
|
|
||||||
const createJob = useMutation(api.agentJobs.createForThread);
|
const createJob = useMutation(api.agentJobs.createForThread);
|
||||||
const markResolved = useMutation(api.threads.markResolved);
|
const markResolved = useMutation(api.threads.markResolved);
|
||||||
const cancel = useMutation(api.threads.cancel);
|
const cancel = useMutation(api.threads.cancel);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import type { FunctionReturnType } from 'convex/server';
|
|
||||||
import { NextResponse } from 'next/server';
|
import { NextResponse } from 'next/server';
|
||||||
import { proxyWorker } from '@/lib/agent-worker-proxy';
|
import { proxyWorker } from '@/lib/agent-worker-proxy';
|
||||||
import { convexAuthNextjsToken } from '@convex-dev/auth/nextjs/server';
|
import { convexAuthNextjsToken } from '@convex-dev/auth/nextjs/server';
|
||||||
@@ -40,7 +39,7 @@ export const POST = async (
|
|||||||
api.threads.get,
|
api.threads.get,
|
||||||
{ threadId },
|
{ threadId },
|
||||||
{ token },
|
{ token },
|
||||||
)) as FunctionReturnType<typeof api.threads.get> | null;
|
));
|
||||||
if (details === null) {
|
if (details === null) {
|
||||||
return NextResponse.json({ error: 'Thread not found.' }, { status: 404 });
|
return NextResponse.json({ error: 'Thread not found.' }, { status: 404 });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import type { FunctionReturnType } from 'convex/server';
|
|
||||||
import type { CSSProperties, PointerEvent as ReactPointerEvent } from 'react';
|
import type { CSSProperties, PointerEvent as ReactPointerEvent } from 'react';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useMutation, useQuery } from 'convex/react';
|
import { useMutation, useQuery } from 'convex/react';
|
||||||
@@ -61,10 +60,7 @@ type PendingOverwrite = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const AgentWorkspaceShell = ({ jobId }: { jobId: Id<'agentJobs'> }) => {
|
export const AgentWorkspaceShell = ({ jobId }: { jobId: Id<'agentJobs'> }) => {
|
||||||
const job = useQuery(api.agentJobs.get, { jobId }) as
|
const job = useQuery(api.agentJobs.get, { jobId });
|
||||||
| FunctionReturnType<typeof api.agentJobs.get>
|
|
||||||
| null
|
|
||||||
| undefined;
|
|
||||||
const messages =
|
const messages =
|
||||||
useQuery(
|
useQuery(
|
||||||
api.agentJobs.listMessages,
|
api.agentJobs.listMessages,
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ const {
|
|||||||
writeTextSpy,
|
writeTextSpy,
|
||||||
} = vi.hoisted(() => ({
|
} = vi.hoisted(() => ({
|
||||||
openSpy: vi.fn(),
|
openSpy: vi.fn(),
|
||||||
wsInstances: [] as Array<{
|
wsInstances: [] as {
|
||||||
url: string;
|
url: string;
|
||||||
send: ReturnType<typeof vi.fn>;
|
send: ReturnType<typeof vi.fn>;
|
||||||
close: ReturnType<typeof vi.fn>;
|
close: ReturnType<typeof vi.fn>;
|
||||||
}>,
|
}[],
|
||||||
fetchSpy: vi.fn(),
|
fetchSpy: vi.fn(),
|
||||||
fitSpy: vi.fn(),
|
fitSpy: vi.fn(),
|
||||||
selectionHandlers: [] as (() => void)[],
|
selectionHandlers: [] as (() => void)[],
|
||||||
@@ -110,17 +110,23 @@ beforeEach(() => {
|
|||||||
fetchSpy.mockResolvedValue({
|
fetchSpy.mockResolvedValue({
|
||||||
ok: true,
|
ok: true,
|
||||||
status: 200,
|
status: 200,
|
||||||
json: async () => ({ url: 'ws://x' }),
|
json: () => Promise.resolve({ url: 'ws://x' }),
|
||||||
text: async () => '',
|
text: () => Promise.resolve(''),
|
||||||
});
|
});
|
||||||
vi.stubGlobal('WebSocket', FakeWebSocket);
|
vi.stubGlobal('WebSocket', FakeWebSocket);
|
||||||
vi.stubGlobal('fetch', fetchSpy);
|
vi.stubGlobal('fetch', fetchSpy);
|
||||||
vi.stubGlobal(
|
vi.stubGlobal(
|
||||||
'ResizeObserver',
|
'ResizeObserver',
|
||||||
class {
|
class {
|
||||||
observe() {}
|
observe() {
|
||||||
disconnect() {}
|
/* noop */
|
||||||
unobserve() {}
|
}
|
||||||
|
disconnect() {
|
||||||
|
/* noop */
|
||||||
|
}
|
||||||
|
unobserve() {
|
||||||
|
/* noop */
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
Object.defineProperty(document, 'fonts', {
|
Object.defineProperty(document, 'fonts', {
|
||||||
|
|||||||
Reference in New Issue
Block a user