diff --git a/exa/language_server_pb/language_server.proto b/exa/language_server_pb/language_server.proto index a324f08..e620593 100644 --- a/exa/language_server_pb/language_server.proto +++ b/exa/language_server_pb/language_server.proto @@ -15,6 +15,12 @@ service LanguageServerService { rpc GetAuthToken(GetAuthTokenRequest) returns (GetAuthTokenResponse) {} } +message MultilineConfig { + // Multiline model threshold. 0-1, higher = more single line, lower = more multiline, + // 0.0 = only_multiline, default is 0.5 + float threshold = 1; +} + // Next ID: 9, Previous field: disable_cache. message GetCompletionsRequest { codeium_common_pb.Metadata metadata = 1 [(validate.rules).message.required = true]; @@ -24,6 +30,7 @@ message GetCompletionsRequest { ExperimentConfig experiment_config = 7; string model_name = 10; + MultilineConfig multiline_config = 13; } // Next ID: 5, Previous field: latency_info. diff --git a/package.json b/package.json index 89a2b6b..504987a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@codeium/react-code-editor", - "version": "1.0.8", + "version": "1.0.12", "description": "AI-powered React component", "main": "dist/index.js", "type": "module", @@ -21,7 +21,7 @@ "storybook": "storybook dev -p 6006 --no-open", "build-storybook": "storybook build", "format": "prettier --write 'src/**/*.{ts,tsx}'", - "prepare": "npm run rollup" + "prepare": "pnpm run generate && pnpm run rollup" }, "repository": { "type": "git", diff --git a/rollup.config.js b/rollup.config.js index 344c7cf..f22f04e 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -5,6 +5,9 @@ import dts from "rollup-plugin-dts"; import banner2 from 'rollup-plugin-banner2' import packageJson from "./package.json" assert { type: "json" }; +const version = packageJson.version ?? null; + + export default [ { input: "src/index.ts", @@ -26,7 +29,11 @@ export default [ commonjs(), typescript({ tsconfig: "./tsconfig.json" }), banner2(() => ` - "use client"; +"use client"; + +if (typeof window !== "undefined") { + window.CODEIUM_REACT_CODE_VERSION = ${version ? `${JSON.stringify(version)}` : null}; +} `) ], }, diff --git a/src/components/CodeiumEditor/CodeiumEditor.tsx b/src/components/CodeiumEditor/CodeiumEditor.tsx index 3266d3c..73911ea 100644 --- a/src/components/CodeiumEditor/CodeiumEditor.tsx +++ b/src/components/CodeiumEditor/CodeiumEditor.tsx @@ -12,6 +12,7 @@ import { LanguageServerService } from '../../api/proto/exa/language_server_pb/la import { InlineCompletionProvider } from './InlineCompletionProvider'; import { CodeiumLogo } from '../CodeiumLogo/CodeiumLogo'; import { Document } from '../../models'; +import { deepMerge } from '../../utils/merge'; export interface CodeiumEditorProps extends EditorProps { language: string; @@ -33,6 +34,23 @@ export interface CodeiumEditorProps extends EditorProps { * documents. */ otherDocuments?: Document[]; + + /** + * Optional classname for the container. + */ + containerClassName?: string; + + /** + * Optional styles for the container. + */ + containerStyle?: React.CSSProperties; + + /** + * Optional multiline model threshold. Should not be needed for most use cases. + * Numerical value between 0-1, higher = more single line, lower = more multiline, + * 0.0 = only_multiline. + */ + multilineModelThreshold?: number; } /** @@ -42,6 +60,8 @@ export interface CodeiumEditorProps extends EditorProps { export const CodeiumEditor: React.FC = ({ languageServerAddress = 'https://web-backend.codeium.com', otherDocuments = [], + containerClassName = '', + containerStyle = {}, ...props }) => { const editorRef = useRef(null); @@ -73,6 +93,7 @@ export const CodeiumEditor: React.FC = ({ setCodeiumStatus, setCodeiumStatusMessage, props.apiKey, + props.multilineModelThreshold, ); }, []); @@ -165,7 +186,9 @@ export const CodeiumEditor: React.FC = ({ style={{ ...layout, position: 'relative', + ...containerStyle, }} + className={containerClassName} > = ({ width={layout.width} height={layout.height} onMount={handleEditorDidMount} - options={{ - scrollBeyondLastColumn: 0, - scrollbar: { - alwaysConsumeMouseWheel: false, - }, - codeLens: false, - // for resizing, but apparently might have "severe performance impact" - // automaticLayout: true, - minimap: { - enabled: false, + options={deepMerge( + props.options, + { + scrollBeyondLastColumn: 0, + scrollbar: { + alwaysConsumeMouseWheel: false, + }, + codeLens: false, + // for resizing, but apparently might have "severe performance impact" + // automaticLayout: true, + minimap: { + enabled: false, + }, + quickSuggestions: false, + folding: false, + foldingHighlight: false, + foldingImportsByDefault: false, + links: false, + fontSize: 14, + wordWrap: 'on', }, - quickSuggestions: false, - folding: false, - foldingHighlight: false, - foldingImportsByDefault: false, - links: false, - fontSize: 14, - wordWrap: 'on', - ...props.options, - }} + )} /> ); diff --git a/src/components/CodeiumEditor/CompletionProvider.ts b/src/components/CodeiumEditor/CompletionProvider.ts index b0df60e..5765362 100644 --- a/src/components/CodeiumEditor/CompletionProvider.ts +++ b/src/components/CodeiumEditor/CompletionProvider.ts @@ -4,6 +4,7 @@ import { Document as DocumentInfo, GetCompletionsResponse, CompletionItem, + MultilineConfig, } from '../../api/proto/exa/language_server_pb/language_server_pb'; import { Document } from './Document'; import { Position, Range } from './Location'; @@ -62,6 +63,7 @@ export class MonacoCompletionProvider { readonly setStatus: (status: Status) => void, readonly setMessage: (message: string) => void, readonly apiKey?: string | undefined, + readonly multilineModelThreshold?: number | undefined, ) { this.sessionId = `react-editor-${uuid()}`; this.client = grpcClient; @@ -131,10 +133,13 @@ export class MonacoCompletionProvider { ); includedOtherDocs = includedOtherDocs.slice(0, 10); } - console.log( - `Included other documents: ${includedOtherDocs.length}`, - includedOtherDocs.map((d) => d.toJson()), - ); + + let multilineConfig: MultilineConfig | undefined = undefined; + if (this.multilineModelThreshold !== undefined) { + multilineConfig = new MultilineConfig({ + threshold: this.multilineModelThreshold, + }); + } // Get completions. let getCompletionsResponse: GetCompletionsResponse; @@ -145,6 +150,7 @@ export class MonacoCompletionProvider { document: documentInfo, editorOptions: editorOptions, otherDocuments: includedOtherDocs, + multilineConfig, }, { signal, diff --git a/src/components/CodeiumEditor/InlineCompletionProvider.ts b/src/components/CodeiumEditor/InlineCompletionProvider.ts index c44b91d..f8be118 100644 --- a/src/components/CodeiumEditor/InlineCompletionProvider.ts +++ b/src/components/CodeiumEditor/InlineCompletionProvider.ts @@ -26,6 +26,7 @@ export class InlineCompletionProvider setCodeiumStatus: Dispatch>, setCodeiumStatusMessage: Dispatch>, apiKey?: string | undefined, + multilineModelThreshold?: number | undefined, ) { this.numCompletionsProvided = 0; this.completionProvider = new MonacoCompletionProvider( @@ -33,6 +34,7 @@ export class InlineCompletionProvider setCodeiumStatus, setCodeiumStatusMessage, apiKey, + multilineModelThreshold, ); } diff --git a/src/stories/CodeiumEditor.stories.tsx b/src/stories/CodeiumEditor.stories.tsx index 0454e40..ae69398 100644 --- a/src/stories/CodeiumEditor.stories.tsx +++ b/src/stories/CodeiumEditor.stories.tsx @@ -137,6 +137,75 @@ export const MarkdownEditor: Story = { }, }; +export const PlainTextEditor: Story = { + decorators: (Story) => ( +
+

Plain Text

+