analyze-content.ts 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import { instructionsForInformationTypes } from '~/features/openai/server/services/assistant/instructions/commons';
  2. import type {
  3. ContentAnalysis,
  4. InformationType,
  5. } from '../../interfaces/suggest-path-types';
  6. import { callLlmForJson } from './call-llm-for-json';
  7. const VALID_INFORMATION_TYPES: readonly InformationType[] = ['flow', 'stock'];
  8. const SYSTEM_PROMPT = [
  9. 'You are a content analysis assistant. Analyze the following content and return a JSON object with two fields:\n',
  10. '1. "keywords": An array of 1 to 5 search keywords extracted from the content. ',
  11. 'Prioritize proper nouns and technical terms over generic or common words.\n',
  12. '2. "informationType": Classify the content as either "flow" or "stock".\n\n',
  13. '## Classification Reference\n',
  14. instructionsForInformationTypes,
  15. '\n\n',
  16. 'Return only the JSON object, no other text.\n',
  17. 'Example: {"keywords": ["React", "useState", "hooks"], "informationType": "stock"}',
  18. ].join('');
  19. const isValidContentAnalysis = (parsed: unknown): parsed is ContentAnalysis => {
  20. if (parsed == null || typeof parsed !== 'object') {
  21. return false;
  22. }
  23. const obj = parsed as Record<string, unknown>;
  24. if (!Array.isArray(obj.keywords) || obj.keywords.length === 0) {
  25. return false;
  26. }
  27. if (
  28. typeof obj.informationType !== 'string' ||
  29. !VALID_INFORMATION_TYPES.includes(obj.informationType as InformationType)
  30. ) {
  31. return false;
  32. }
  33. return true;
  34. };
  35. export const analyzeContent = (body: string): Promise<ContentAnalysis> => {
  36. return callLlmForJson(
  37. SYSTEM_PROMPT,
  38. body,
  39. isValidContentAnalysis,
  40. 'Invalid content analysis response: expected { keywords: string[], informationType: "flow" | "stock" }',
  41. );
  42. };