llama-vscode.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import { useEffect } from 'react';
  2. import { ChatTextareaApi } from '../components/useChatTextarea.ts';
  3. import { ChatExtraContextApi } from '../components/useChatExtraContext.tsx';
  4. // Extra context when using llama.cpp WebUI from llama-vscode, inside an iframe
  5. // Ref: https://github.com/ggml-org/llama.cpp/pull/11940
  6. interface SetTextEvData {
  7. text: string;
  8. context: string;
  9. }
  10. /**
  11. * To test it:
  12. * window.postMessage({ command: 'setText', text: 'Spot the syntax error', context: 'def test()\n return 123' }, '*');
  13. */
  14. export const useVSCodeContext = (
  15. textarea: ChatTextareaApi,
  16. extraContext: ChatExtraContextApi
  17. ) => {
  18. // Accept setText message from a parent window and set inputMsg and extraContext
  19. useEffect(() => {
  20. const handleMessage = (event: MessageEvent) => {
  21. if (event.data?.command === 'setText') {
  22. const data: SetTextEvData = event.data;
  23. textarea.setValue(data?.text);
  24. if (data?.context && data.context.length > 0) {
  25. extraContext.clearItems();
  26. extraContext.addItems([
  27. {
  28. type: 'context',
  29. name: 'Extra context',
  30. content: data.context,
  31. },
  32. ]);
  33. }
  34. textarea.focus();
  35. setTimeout(() => {
  36. textarea.refOnSubmit.current?.();
  37. }, 10); // wait for setExtraContext to finish
  38. }
  39. };
  40. window.addEventListener('message', handleMessage);
  41. return () => window.removeEventListener('message', handleMessage);
  42. }, [textarea, extraContext]);
  43. // Add a keydown listener that sends the "escapePressed" message to the parent window
  44. useEffect(() => {
  45. const handleKeyDown = (event: KeyboardEvent) => {
  46. if (event.key === 'Escape') {
  47. window.parent.postMessage({ command: 'escapePressed' }, '*');
  48. }
  49. };
  50. window.addEventListener('keydown', handleKeyDown);
  51. return () => window.removeEventListener('keydown', handleKeyDown);
  52. }, []);
  53. return {};
  54. };