Skip to content

Commit a269586

Browse files
committed
Merge branch 'nightly' of github.com:cloudflare/vibesdk into feat/prompt-optimizations
2 parents 69c8642 + 8927bf0 commit a269586

File tree

7 files changed

+56
-9
lines changed

7 files changed

+56
-9
lines changed

src/api-types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ export type {
203203

204204
export type { RateLimitError } from "worker/services/rate-limit/errors";
205205
export type { AgentPreviewResponse, CodeGenArgs } from 'worker/api/controllers/agent/types';
206+
export { MAX_AGENT_QUERY_LENGTH } from 'worker/api/controllers/agent/types';
206207
export type { RateLimitErrorResponse } from 'worker/api/responses';
207208
export { RateLimitExceededError, SecurityError, SecurityErrorType } from '../shared/types/errors.js';
208209

src/lib/api-client.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -592,11 +592,16 @@ class ApiClient {
592592

593593
async createAgentSession(args: CodeGenArgs): Promise<AgentStreamingResponse> {
594594
try {
595-
const { response, data } = await this.requestRaw('/api/agent', {
596-
method: 'POST',
597-
body: args,
598-
skipJsonParsing: true, // Don't parse JSON for streaming response
599-
});
595+
const { response, data } = await this.requestRaw(
596+
'/api/agent',
597+
{
598+
method: 'POST',
599+
body: args,
600+
skipJsonParsing: true, // Don't parse JSON for streaming response
601+
},
602+
false,
603+
true,
604+
);
600605

601606
// Check if response is ok
602607
if (!response.ok) {

src/routes/chat/hooks/use-chat.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
33
import { toast } from 'sonner';
44
import {
55
RateLimitExceededError,
6+
MAX_AGENT_QUERY_LENGTH,
67
type BlueprintType,
78
type WebSocketMessage,
89
type CodeFixEdits,
@@ -447,6 +448,13 @@ export function useChat({
447448
return;
448449
}
449450

451+
if (userQuery.length > MAX_AGENT_QUERY_LENGTH) {
452+
const errorMsg = `Prompt too large (${userQuery.length} characters). Maximum allowed is ${MAX_AGENT_QUERY_LENGTH} characters.`;
453+
toast.error(errorMsg);
454+
setMessages(() => [createAIMessage('main', errorMsg)]);
455+
return;
456+
}
457+
450458
// Prevent duplicate session creation on rerenders while streaming
451459
connectionStatus.current = 'connecting';
452460

src/routes/home.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { ArrowRight, Info } from 'react-feather';
33
import { useNavigate } from 'react-router';
44
import { useAuth } from '@/contexts/auth-context';
55
import { ProjectModeSelector, type ProjectModeOption } from '../components/project-mode-selector';
6-
import type { ProjectType } from '@/api-types';
6+
import { MAX_AGENT_QUERY_LENGTH, SUPPORTED_IMAGE_MIME_TYPES, type ProjectType } from '@/api-types';
77
import { useFeature } from '@/features';
88
import { useAuthGuard } from '../hooks/useAuthGuard';
99
import { usePaginatedApps } from '@/hooks/use-paginated-apps';
@@ -14,7 +14,6 @@ import { useImageUpload } from '@/hooks/use-image-upload';
1414
import { useDragDrop } from '@/hooks/use-drag-drop';
1515
import { ImageUploadButton } from '@/components/image-upload-button';
1616
import { ImageAttachmentPreview } from '@/components/image-attachment-preview';
17-
import { SUPPORTED_IMAGE_MIME_TYPES } from '@/api-types';
1817
import { toast } from 'sonner';
1918

2019
export default function Home() {
@@ -89,6 +88,13 @@ export default function Home() {
8988
const discoverReady = useMemo(() => !loading && (apps?.length ?? 0) > 5, [loading, apps]);
9089

9190
const handleCreateApp = (query: string, mode: ProjectType) => {
91+
if (query.length > MAX_AGENT_QUERY_LENGTH) {
92+
toast.error(
93+
`Prompt too large (${query.length} characters). Maximum allowed is ${MAX_AGENT_QUERY_LENGTH} characters.`,
94+
);
95+
return;
96+
}
97+
9298
const encodedQuery = encodeURIComponent(query);
9399
const encodedMode = encodeURIComponent(mode);
94100

worker/agents/core/stateMigration.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { StructuredLogger } from '../../logger';
33
import { TemplateDetails } from 'worker/services/sandbox/sandboxTypes';
44
import { generateNanoId } from '../../utils/idGenerator';
55
import { generateProjectName } from '../utils/templateCustomizer';
6+
import { MAX_AGENT_QUERY_LENGTH } from 'worker/api/controllers/agent/types';
67

78
// Type guards for legacy state detection
89
type LegacyFileFormat = {
@@ -38,6 +39,14 @@ export class StateMigration {
3839
static migrateIfNeeded(state: AgentState, logger: StructuredLogger): AgentState | null {
3940
let needsMigration = false;
4041

42+
43+
// If the query is too long, truncate it to avoid performance issues
44+
if (state.query && state.query.length > MAX_AGENT_QUERY_LENGTH) {
45+
logger.warn("Large prompt detected. Truncating query to avoid performance issues");
46+
state.query = state.query.slice(0, MAX_AGENT_QUERY_LENGTH);
47+
needsMigration = true;
48+
}
49+
4150
//------------------------------------------------------------------------------------
4251
// Migrate files from old schema
4352
//------------------------------------------------------------------------------------

worker/api/controllers/agent/controller.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ import { generateId } from '../../../utils/idGenerator';
44
import { AgentState } from '../../../agents/core/state';
55
import { BehaviorType, ProjectType } from '../../../agents/core/types';
66
import { getAgentStub, getTemplateForQuery } from '../../../agents';
7-
import { AgentConnectionData, AgentPreviewResponse, CodeGenArgs } from './types';
7+
import {
8+
AgentConnectionData,
9+
AgentPreviewResponse,
10+
CodeGenArgs,
11+
MAX_AGENT_QUERY_LENGTH,
12+
} from './types';
13+
import { SecurityError, SecurityErrorType } from 'shared/types/errors';
814
import { ApiResponse, ControllerResponse } from '../types';
915
import { RouteContext } from '../../types/route-context';
1016
import { ModelConfigService } from '../../../database';
@@ -59,9 +65,19 @@ export class CodingAgentController extends BaseController {
5965
}
6066

6167
const query = body.query;
62-
if (!query) {
68+
if (typeof query !== 'string' || query.trim().length === 0) {
6369
return CodingAgentController.createErrorResponse('Missing "query" field in request body', 400);
6470
}
71+
if (query.length > MAX_AGENT_QUERY_LENGTH) {
72+
return CodingAgentController.createErrorResponse(
73+
new SecurityError(
74+
SecurityErrorType.INVALID_INPUT,
75+
`Prompt too large (${query.length} characters). Maximum allowed is ${MAX_AGENT_QUERY_LENGTH} characters.`,
76+
413,
77+
),
78+
413,
79+
);
80+
}
6581
const { readable, writable } = new TransformStream({
6682
transform(chunk, controller) {
6783
if (chunk === "terminate") {

worker/api/controllers/agent/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import type { PreviewType } from "../../../services/sandbox/sandboxTypes";
22
import type { ImageAttachment } from '../../../types/image-attachment';
33
import type { BehaviorType, ProjectType } from '../../../agents/core/types';
44

5+
export const MAX_AGENT_QUERY_LENGTH = 20_000;
6+
57
export interface CodeGenArgs {
68
query: string;
79
language?: string;

0 commit comments

Comments
 (0)