(
@Body() chatDto: ChatRestDto,
@Res() res: Response,
@GetAuthToken() userId: string,
)
| 17 | import { WorkspaceService } from '../project/workspace.service'; |
| 18 | import type { ChangedFile } from '../project/workspace'; |
| 19 | import { lintArtifact, type LintFinding } from './lint-artifact'; |
| 20 | import { validateExternalApiBaseUrl } from './external-url'; |
| 21 | import { |
| 22 | atTurnLimit, |
| 23 | busy, |
| 24 | queueForProject, |
| 25 | turnLimit, |
| 26 | withUserTurn, |
| 27 | } from '../project/project-queue'; |
| 28 | import { scenarioOfPage } from '../project/scenarios'; |
| 29 | import { clipNotes, HISTORY_TURNS } from './instructions'; |
| 30 | |
| 31 | /** |
| 32 | * Best-effort label for what a tool call is acting on. Tool arguments arrive as |
| 33 | * a JSON string whose shape is the tool's own, so this reads the keys the |
| 34 | * built-in file tools happen to use and gives up quietly otherwise. |
| 35 | */ |
| 36 | const PATH_KEYS = ['file_path', 'filePath', 'path', 'notebook_path']; |
| 37 | |
| 38 | const targetOf = (input: unknown): string | undefined => { |
| 39 | // Typed as a string, but tolerate an already-parsed object: the label is a |
| 40 | // nicety and must never be the reason a turn fails. |
| 41 | let args: any = input; |
| 42 | if (typeof args === 'string') { |
| 43 | try { |
| 44 | args = JSON.parse(args); |
| 45 | } catch { |
| 46 | return args.length <= 40 ? args : undefined; |
| 47 | } |
| 48 | } |
| 49 | if (!args || typeof args !== 'object') return undefined; |
| 50 | |
| 51 | for (const key of PATH_KEYS) { |
| 52 | const value = args[key]; |
| 53 | if (typeof value === 'string' && value) return value.split('/').pop(); |
| 54 | } |
| 55 | if (typeof args.command === 'string') return args.command.slice(0, 40); |
| 56 | if (typeof args.pattern === 'string') return args.pattern.slice(0, 40); |
| 57 | return undefined; |
| 58 | }; |
| 59 | |
| 60 | @Controller('api/chat') |
| 61 | @UseGuards(JWTAuthGuard, ChatGuard) |
| 62 | export class ChatController { |
| 63 | private readonly logger = new Logger(ChatController.name); |
| 64 | |
| 65 | constructor( |
| 66 | private readonly chatService: ChatService, |
| 67 | private readonly workspaces: WorkspaceService, |
| 68 | @InjectRepository(AgentTurn) |
| 69 | private readonly turns: Repository<AgentTurn>, |
nothing calls this directly
no test coverage detected