mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-26 00:01:37 +00:00
feat(frontend): generate scripts in the flow and app builders (#1886)
* feat: add inline code gen flow * feat(frontend): add script gen to flow and app builders * fix(backend): allow all users to use openai * Fix build * Fix build * Fix build --------- Co-authored-by: Faton Ramadani <faton.ramadani14@gmail.com>
This commit is contained in:
@@ -27,8 +27,6 @@ async fn proxy(
|
||||
Path((w_id, openai_path)): Path<(String, String)>,
|
||||
body: Bytes,
|
||||
) -> impl IntoResponse {
|
||||
tracing::info!("reached openai endpoint");
|
||||
|
||||
let mut tx = db.begin().await?;
|
||||
let settings = sqlx::query_as!(
|
||||
OpenAIKey,
|
||||
|
||||
@@ -707,9 +707,7 @@ async fn edit_openai_key(
|
||||
async fn exists_openai_key(
|
||||
Extension(db): Extension<DB>,
|
||||
Path(w_id): Path<String>,
|
||||
Authed { is_admin, username, .. }: Authed,
|
||||
) -> JsonResult<bool> {
|
||||
require_admin(is_admin, &username)?;
|
||||
|
||||
let mut tx = db.begin().await?;
|
||||
let openai_key = sqlx::query_scalar!(
|
||||
|
||||
Generated
+98
@@ -46,6 +46,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@floating-ui/core": "^1.3.1",
|
||||
"@modyfi/vite-plugin-yaml": "^1.0.4",
|
||||
"@playwright/test": "^1.34.3",
|
||||
"@rgossiaux/svelte-headlessui": "^1.0.2",
|
||||
"@sveltejs/adapter-static": "^2.0.2",
|
||||
@@ -703,6 +704,20 @@
|
||||
"integrity": "sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@modyfi/vite-plugin-yaml": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@modyfi/vite-plugin-yaml/-/vite-plugin-yaml-1.0.4.tgz",
|
||||
"integrity": "sha512-qkT0KiR3AQQRfUvDzLv4+1rYAzXj+QmGhAbyUd0Ordf9xynK76i758lk5GiEfxuQxbvdqDaJ9oXkH/KacbSjQQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "5.0.2",
|
||||
"js-yaml": "4.1.0",
|
||||
"tosource": "2.0.0-alpha.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vite": "^2.6.0 || ^3.0.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@@ -792,6 +807,28 @@
|
||||
"svelte": "^3.44.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/pluginutils": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
|
||||
"integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^1.20.0||^2.0.0||^3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@sveltejs/adapter-static": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-2.0.2.tgz",
|
||||
@@ -1219,6 +1256,12 @@
|
||||
"@types/d3-selection": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
|
||||
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/geojson": {
|
||||
"version": "7946.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
|
||||
@@ -3383,6 +3426,12 @@
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/esutils": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
||||
@@ -7844,6 +7893,15 @@
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tosource": {
|
||||
"version": "2.0.0-alpha.3",
|
||||
"resolved": "https://registry.npmjs.org/tosource/-/tosource-2.0.0-alpha.3.tgz",
|
||||
"integrity": "sha512-KAB2lrSS48y91MzFPFuDg4hLbvDiyTjOVgaK7Erw+5AmZXNq4sFRVn8r6yxSLuNs15PaokrDRpS61ERY9uZOug==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/totalist": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.0.tgz",
|
||||
@@ -8861,6 +8919,17 @@
|
||||
"integrity": "sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA==",
|
||||
"dev": true
|
||||
},
|
||||
"@modyfi/vite-plugin-yaml": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@modyfi/vite-plugin-yaml/-/vite-plugin-yaml-1.0.4.tgz",
|
||||
"integrity": "sha512-qkT0KiR3AQQRfUvDzLv4+1rYAzXj+QmGhAbyUd0Ordf9xynK76i758lk5GiEfxuQxbvdqDaJ9oXkH/KacbSjQQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@rollup/pluginutils": "5.0.2",
|
||||
"js-yaml": "4.1.0",
|
||||
"tosource": "2.0.0-alpha.3"
|
||||
}
|
||||
},
|
||||
"@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@@ -8927,6 +8996,17 @@
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"@rollup/pluginutils": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
|
||||
"integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@sveltejs/adapter-static": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-2.0.2.tgz",
|
||||
@@ -9291,6 +9371,12 @@
|
||||
"@types/d3-selection": "*"
|
||||
}
|
||||
},
|
||||
"@types/estree": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
|
||||
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/geojson": {
|
||||
"version": "7946.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
|
||||
@@ -10812,6 +10898,12 @@
|
||||
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
|
||||
"dev": true
|
||||
},
|
||||
"estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"dev": true
|
||||
},
|
||||
"esutils": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
||||
@@ -14040,6 +14132,12 @@
|
||||
"is-number": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"tosource": {
|
||||
"version": "2.0.0-alpha.3",
|
||||
"resolved": "https://registry.npmjs.org/tosource/-/tosource-2.0.0-alpha.3.tgz",
|
||||
"integrity": "sha512-KAB2lrSS48y91MzFPFuDg4hLbvDiyTjOVgaK7Erw+5AmZXNq4sFRVn8r6yxSLuNs15PaokrDRpS61ERY9uZOug==",
|
||||
"dev": true
|
||||
},
|
||||
"totalist": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.0.tgz",
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@floating-ui/core": "^1.3.1",
|
||||
"@modyfi/vite-plugin-yaml": "^1.0.4",
|
||||
"@playwright/test": "^1.34.3",
|
||||
"@rgossiaux/svelte-headlessui": "^1.0.2",
|
||||
"@sveltejs/adapter-static": "^2.0.2",
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
import 'monaco-editor/esm/vs/basic-languages/typescript/typescript.contribution'
|
||||
import 'monaco-editor/esm/vs/basic-languages/sql/sql.contribution'
|
||||
import 'monaco-editor/esm/vs/language/typescript/monaco.contribution'
|
||||
import { Breakpoints } from './apps/gridUtils'
|
||||
|
||||
meditor.defineTheme('myTheme', {
|
||||
base: 'vs',
|
||||
@@ -23,17 +22,19 @@
|
||||
})
|
||||
meditor.setTheme('myTheme')
|
||||
|
||||
const SIDE_BY_SIDE_MIN_WIDTH = 650
|
||||
|
||||
export let automaticLayout = true
|
||||
export let fixedOverflowWidgets = true
|
||||
export let sideBySideMinWidth = Breakpoints.lg
|
||||
|
||||
let diffEditor: meditor.IStandaloneDiffEditor
|
||||
let diffEditor: meditor.IStandaloneDiffEditor | undefined
|
||||
let diffDivEl: HTMLDivElement | null = null
|
||||
let editorWidth: number = SIDE_BY_SIDE_MIN_WIDTH
|
||||
|
||||
function loadDiffEditor() {
|
||||
diffEditor = meditor.createDiffEditor(diffDivEl!, {
|
||||
automaticLayout,
|
||||
renderSideBySide: window.innerWidth >= sideBySideMinWidth,
|
||||
renderSideBySide: editorWidth >= SIDE_BY_SIDE_MIN_WIDTH,
|
||||
domReadOnly: true,
|
||||
readOnly: true,
|
||||
minimap: {
|
||||
@@ -51,9 +52,9 @@
|
||||
export function setDiff(
|
||||
original: string,
|
||||
modified: string,
|
||||
lang: 'typescript' | 'python' | 'go' | 'shell' | 'sql' | 'graphql'
|
||||
lang: 'typescript' | 'python' | 'go' | 'shell' | 'sql' | 'graphql' | 'javascript'
|
||||
): void {
|
||||
diffEditor.setModel({
|
||||
diffEditor?.setModel({
|
||||
original: meditor.createModel(original, lang),
|
||||
modified: meditor.createModel(modified, lang)
|
||||
})
|
||||
@@ -64,11 +65,11 @@
|
||||
}
|
||||
|
||||
export function getOriginal(): string {
|
||||
return diffEditor.getModel()?.original.getValue() ?? ''
|
||||
return diffEditor?.getModel()?.original.getValue() ?? ''
|
||||
}
|
||||
|
||||
export function getModified(): string {
|
||||
return diffEditor.getModel()?.modified.getValue() ?? ''
|
||||
return diffEditor?.getModel()?.modified.getValue() ?? ''
|
||||
}
|
||||
|
||||
export function show(): void {
|
||||
@@ -78,20 +79,20 @@
|
||||
diffDivEl?.classList.add('hidden')
|
||||
}
|
||||
|
||||
function onResize() {
|
||||
diffEditor.updateOptions({ renderSideBySide: window.innerWidth >= sideBySideMinWidth })
|
||||
function onWidthChange(editorWidth: number) {
|
||||
diffEditor?.updateOptions({ renderSideBySide: editorWidth >= SIDE_BY_SIDE_MIN_WIDTH })
|
||||
}
|
||||
|
||||
$: onWidthChange(editorWidth)
|
||||
|
||||
onMount(() => {
|
||||
if (BROWSER) {
|
||||
loadDiffEditor()
|
||||
window.addEventListener('resize', onResize)
|
||||
return () => {
|
||||
diffEditor?.dispose()
|
||||
window.removeEventListener('resize', onResize)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<div bind:this={diffDivEl} class="{$$props.class} editor" />
|
||||
<div bind:this={diffDivEl} class="{$$props.class} editor" bind:clientWidth={editorWidth} />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { Schema } from '$lib/common'
|
||||
import { ScriptService, type FlowModule, type Job } from '$lib/gen'
|
||||
import { ScriptService, type FlowModule, type Job, Script } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getModifierKey } from '$lib/utils'
|
||||
import { getScriptByPath } from '$lib/scripts'
|
||||
@@ -17,10 +17,15 @@
|
||||
import { Kbd } from './common'
|
||||
import { evalValue } from './flows/utils'
|
||||
import type { PickableProperties } from './flows/previousResults'
|
||||
import type DiffEditor from './DiffEditor.svelte'
|
||||
import type Editor from './Editor.svelte'
|
||||
|
||||
export let mod: FlowModule
|
||||
export let schema: Schema
|
||||
export let pickableProperties: PickableProperties | undefined
|
||||
export let lang: Script.language
|
||||
export let editor: Editor
|
||||
export let diffEditor: DiffEditor
|
||||
|
||||
const { flowStore, flowStateStore, testStepStore } =
|
||||
getContext<FlowEditorContext>('FlowEditorContext')
|
||||
@@ -112,7 +117,14 @@
|
||||
<Pane size={50} minSize={10} class="text-sm text-gray-600">
|
||||
{#if testJob != undefined && 'result' in testJob && testJob.result != undefined}
|
||||
<pre class="overflow-x-auto break-words relative h-full px-2">
|
||||
<DisplayResult workspaceId={testJob?.workspace_id} jobId={testJob?.id} result={testJob.result} />
|
||||
<DisplayResult
|
||||
workspaceId={testJob?.workspace_id}
|
||||
jobId={testJob?.id}
|
||||
result={testJob.result}
|
||||
{editor}
|
||||
{diffEditor}
|
||||
{lang}
|
||||
/>
|
||||
</pre>
|
||||
{:else}
|
||||
<div class="p-2">
|
||||
|
||||
@@ -303,7 +303,7 @@
|
||||
bind:this={diffEditor}
|
||||
automaticLayout
|
||||
{fixedOverflowWidgets}
|
||||
class="hidden flex-1 h-full !overflow-visible"
|
||||
class="hidden h-full"
|
||||
/>
|
||||
{/key}
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
KeyCode,
|
||||
KeyMod,
|
||||
Uri as mUri,
|
||||
languages
|
||||
languages,
|
||||
type IRange
|
||||
} from 'monaco-editor/esm/vs/editor/editor.api'
|
||||
import 'monaco-editor/esm/vs/basic-languages/sql/sql.contribution'
|
||||
import 'monaco-editor/esm/vs/basic-languages/yaml/yaml.contribution'
|
||||
@@ -100,6 +101,35 @@
|
||||
editor?.focus()
|
||||
}
|
||||
|
||||
export function getSelectedLines(): string | undefined {
|
||||
if (editor) {
|
||||
const selection = editor.getSelection()
|
||||
if (selection) {
|
||||
const range: IRange = {
|
||||
startLineNumber: selection.startLineNumber,
|
||||
startColumn: 1,
|
||||
endLineNumber: selection.endLineNumber + 1,
|
||||
endColumn: 1
|
||||
}
|
||||
return editor.getModel()?.getValueInRange(range)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function onDidChangeCursorSelection(f: (e: meditor.ICursorSelectionChangedEvent) => void) {
|
||||
if (editor) {
|
||||
return editor.onDidChangeCursorSelection(f)
|
||||
}
|
||||
}
|
||||
|
||||
export function show(): void {
|
||||
divEl?.classList.remove('hidden')
|
||||
}
|
||||
|
||||
export function hide(): void {
|
||||
divEl?.classList.add('hidden')
|
||||
}
|
||||
|
||||
let width = 0
|
||||
async function loadMonaco() {
|
||||
model = meditor.createModel(code, lang, mUri.parse(uri))
|
||||
|
||||
+18
-1
@@ -18,6 +18,8 @@
|
||||
import { buildExtraLib } from '../../utils'
|
||||
import RunButton from './RunButton.svelte'
|
||||
import { scriptLangToEditorLang } from '$lib/scripts'
|
||||
import ScriptGen from '$lib/components/codeGen/ScriptGen.svelte'
|
||||
import DiffEditor from '$lib/components/DiffEditor.svelte'
|
||||
|
||||
let inlineScriptEditorDrawer: InlineScriptEditorDrawer
|
||||
|
||||
@@ -33,7 +35,8 @@
|
||||
const { runnableComponents, stateId, worldStore, state, appPath, app } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
let editor: Editor
|
||||
export let editor: Editor | undefined = undefined
|
||||
let diffEditor: DiffEditor
|
||||
let simpleEditor: SimpleEditor
|
||||
let validCode = true
|
||||
|
||||
@@ -152,6 +155,13 @@
|
||||
<Badge color="red" baseClass="!text-2xs">Invalid</Badge>
|
||||
{/if}
|
||||
|
||||
<ScriptGen
|
||||
lang={inlineScript?.language}
|
||||
editor={inlineScript?.language === 'frontend' ? simpleEditor : editor}
|
||||
{diffEditor}
|
||||
inlineScript
|
||||
/>
|
||||
|
||||
<Button
|
||||
title="Delete"
|
||||
size="xs"
|
||||
@@ -252,6 +262,13 @@
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<DiffEditor
|
||||
bind:this={diffEditor}
|
||||
class="hidden h-full"
|
||||
automaticLayout
|
||||
fixedOverflowWidgets
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -13,12 +13,14 @@
|
||||
import type DiffEditor from '../DiffEditor.svelte'
|
||||
import { scriptLangToEditorLang } from '$lib/scripts'
|
||||
import type { Selection } from 'monaco-editor/esm/vs/editor/editor.api'
|
||||
import type SimpleEditor from '../SimpleEditor.svelte'
|
||||
|
||||
// props
|
||||
export let iconOnly: boolean = false
|
||||
export let lang: SupportedLanguage
|
||||
export let editor: Editor | undefined
|
||||
export let lang: SupportedLanguage | 'frontend'
|
||||
export let editor: Editor | SimpleEditor | undefined
|
||||
export let diffEditor: DiffEditor | undefined
|
||||
export let inlineScript = false
|
||||
|
||||
// state
|
||||
let funcDesc: string = ''
|
||||
@@ -73,7 +75,7 @@
|
||||
generatedCode = ''
|
||||
}
|
||||
|
||||
async function checkIfOpenAIAvailable(lang: SupportedLanguage) {
|
||||
async function checkIfOpenAIAvailable(lang: SupportedLanguage | 'frontend') {
|
||||
try {
|
||||
const exists = $existsOpenaiKeyStore
|
||||
openAIAvailable = exists && SUPPORTED_LANGUAGES.has(lang)
|
||||
@@ -84,7 +86,11 @@
|
||||
}
|
||||
|
||||
function showDiff() {
|
||||
diffEditor?.setDiff(editor?.getCode() || '', generatedCode, scriptLangToEditorLang(lang))
|
||||
diffEditor?.setDiff(
|
||||
editor?.getCode() || '',
|
||||
generatedCode,
|
||||
lang === 'frontend' ? 'javascript' : scriptLangToEditorLang(lang)
|
||||
)
|
||||
diffEditor?.show()
|
||||
editor?.hide()
|
||||
}
|
||||
@@ -114,32 +120,63 @@
|
||||
|
||||
{#if openAIAvailable}
|
||||
{#if generatedCode}
|
||||
<div class="flex gap-1 px-2">
|
||||
<Button
|
||||
title="Discard generated code"
|
||||
btnClasses="!font-medium"
|
||||
size="xs"
|
||||
color="red"
|
||||
spacingSize="xs2"
|
||||
on:click={rejectDiff}
|
||||
variant="contained"
|
||||
startIcon={{ icon: faClose }}
|
||||
{iconOnly}
|
||||
>
|
||||
Discard
|
||||
</Button><Button
|
||||
title="Accept generated code"
|
||||
btnClasses="!font-medium"
|
||||
size="xs"
|
||||
color="green"
|
||||
spacingSize="xs2"
|
||||
on:click={acceptDiff}
|
||||
startIcon={{ icon: faCheck }}
|
||||
{iconOnly}
|
||||
>
|
||||
Accept
|
||||
</Button>
|
||||
</div>
|
||||
{#if inlineScript}
|
||||
<div class="flex gap-1">
|
||||
<Button
|
||||
title="Discard generated code"
|
||||
btnClasses="!font-medium px-2 w-7"
|
||||
size="xs"
|
||||
color="red"
|
||||
on:click={rejectDiff}
|
||||
variant="contained"
|
||||
>
|
||||
<Icon data={faClose} />
|
||||
</Button><Button
|
||||
title="Accept generated code"
|
||||
btnClasses="!font-medium px-2 w-7"
|
||||
size="xs"
|
||||
color="green"
|
||||
on:click={acceptDiff}
|
||||
>
|
||||
<Icon data={faCheck} /></Button
|
||||
>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex gap-1 px-2">
|
||||
<Button
|
||||
title="Discard generated code"
|
||||
btnClasses="!font-medium px-2"
|
||||
size="xs"
|
||||
color="red"
|
||||
on:click={rejectDiff}
|
||||
variant="contained"
|
||||
startIcon={{ icon: faClose }}
|
||||
{iconOnly}
|
||||
>
|
||||
Discard
|
||||
</Button><Button
|
||||
title="Accept generated code"
|
||||
btnClasses="!font-medium px-2"
|
||||
size="xs"
|
||||
color="green"
|
||||
on:click={acceptDiff}
|
||||
startIcon={{ icon: faCheck }}
|
||||
{iconOnly}
|
||||
>
|
||||
Accept
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
{:else if inlineScript}
|
||||
<Button
|
||||
size="lg"
|
||||
bind:element={button}
|
||||
color="light"
|
||||
btnClasses="!px-2 !bg-gray-100 hover:!bg-gray-200"
|
||||
loading={genLoading}
|
||||
>
|
||||
<Icon scale={0.8} data={faMagicWandSparkles} />
|
||||
</Button>
|
||||
{:else}
|
||||
<Button
|
||||
title="Generate code from prompt"
|
||||
@@ -155,7 +192,7 @@
|
||||
{isEdit ? 'AI Edit' : 'AI Gen'}
|
||||
</Button>
|
||||
{/if}
|
||||
{#if !generatedCode}
|
||||
{#if !generatedCode && !genLoading}
|
||||
<Popup
|
||||
ref={button}
|
||||
options={{ placement: 'top-start' }}
|
||||
|
||||
@@ -6,6 +6,8 @@ import { existsOpenaiKeyStore, workspaceStore } from '$lib/stores'
|
||||
import { formatResourceTypes } from './utils'
|
||||
import { scriptLangToEditorLang } from '$lib/scripts'
|
||||
|
||||
import { EDIT_CONFIG, FIX_CONFIG, GEN_CONFIG } from './prompts'
|
||||
|
||||
const WARNING_MSG =
|
||||
'WARNING: this code was generated by OpenAI, it might not be accurate. Use at your own risk.'
|
||||
|
||||
@@ -17,64 +19,25 @@ const COMMENT_TYPES = {
|
||||
[Script.language.POSTGRESQL]: '--',
|
||||
[Script.language.MYSQL]: '--',
|
||||
[Script.language.NATIVETS]: '//',
|
||||
[Script.language.BUN]: '//'
|
||||
[Script.language.BUN]: '//',
|
||||
frontend: '//'
|
||||
}
|
||||
|
||||
const PROMPTS = {
|
||||
[Script.language
|
||||
.PYTHON3]: `Write a function in python called "main". The function should {description}. Specify the parameter types. Do not call the main function.
|
||||
You have access to the following resource types, if you need them, you have to define the TypedDict exactly as specified (class name has to be IN LOWERCASE) and add them as parameters: {resourceTypes}
|
||||
If the TypedDict name conflicts with the imported object, rename the imported object NOT THE TYPE.`,
|
||||
[Script.language
|
||||
.DENO]: `Write a function in typescript called "main". The function should {description}. Specify the parameter types. You are in a Deno environment. You can import deno libraries or you can also import npm libraries like that: "import ... from "npm:{package}";". Export the "main" function like this: "export function main(...)". Do not call the main function.
|
||||
You have access to the following resource types, if you need them, you have to define the type exactly as specified and add them as parameters: {resourceTypes}
|
||||
If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.`,
|
||||
[Script.language.GO]:
|
||||
'Write a function in go called "main". The function should {description}. Import the packages you need. The return type of the function has to be ({return_type}, error). The file package has to be "inner".',
|
||||
[Script.language.BASH]:
|
||||
'Write bash code that should {description}. Do not include "#!/bin/bash". Arguments are always string and can only be obtained with "var1="$1"", "var2="$2"", etc... You do not need to check if the arguments are present.',
|
||||
[Script.language.POSTGRESQL]:
|
||||
'Write SQL code for a PostgreSQL that should {description}. Arguments can be obtained directly in the statement with $1::{type}, $2::{type}, etc... Name the parameters by adding comments before the command like that: -- $1 name1 (one per row, do not include the type)',
|
||||
[Script.language.MYSQL]:
|
||||
'Write SQL code for MySQL that should {description}. Arguments can be obtained directly in the statement with ?. Name the parameters by adding comments before the command like that: -- ? name1 ({type}) (one per row)',
|
||||
[Script.language
|
||||
.NATIVETS]: `Write a function in typescript called "main". The function should {description}. Specify the parameter types. You should use fetch and are not allowed to import any libraries. Export the "main" function like this: "export function main(...)". Do not call the main function.
|
||||
You have access to the following resource types, if you need them, you have to define the type exactly as specified and add them as parameters: {resourceTypes}
|
||||
If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.`,
|
||||
[Script.language
|
||||
.BUN]: `Write a function in typescript called "main". The function should {description}. Specify the parameter types. You are in a Node.js environment. You can import npm libraries. Export the "main" function like this: "export function main(...)". Do not call the main function.
|
||||
You have access to the following resource types, if you need them, you have to define the type exactly as specified and add them as parameters: {resourceTypes}
|
||||
If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.`
|
||||
}
|
||||
|
||||
function scriptLangToEnvironment(lang: Script.language) {
|
||||
function scriptLangToEnvironment(lang: Script.language | 'frontend') {
|
||||
if (lang === Script.language.DENO) {
|
||||
return 'typescript in a deno running environment'
|
||||
} else if (lang === Script.language.BUN) {
|
||||
return 'typescript in a node.js running environment'
|
||||
} else if (lang === Script.language.NATIVETS) {
|
||||
return 'typescript where you should use fetch and are not allowed to import any libraries'
|
||||
} else if (lang === 'frontend') {
|
||||
return 'client-side javascript'
|
||||
} else {
|
||||
return lang
|
||||
}
|
||||
}
|
||||
|
||||
const SYSTEM_PROMPT =
|
||||
'You write code as queried by the user. Only output code. Wrap the code like that: ```language\n{code}\n```. Put any explanation directly in the code as comments.'
|
||||
|
||||
const EDIT_SYSTEM_PROMPT =
|
||||
'You edit the code as queried by the user. Only output code. Wrap the code like that: ```language\n{code}\n```. Put any explanation directly in the code as comments.'
|
||||
|
||||
const EDIT_PROMPT =
|
||||
"Here's my environement: {environment}\nHere's my code: ```{lang}\n{code}\n```\nMy instructions: {description}"
|
||||
|
||||
const FIX_PROMPT =
|
||||
"Here's my environement: {environment}\nHere's my code: ```{lang}\n{code}\n```\nI get the following error: {error}\nFix it for me."
|
||||
|
||||
const FIX_SYSTEM_PROMPT =
|
||||
'You fix the code shared by the user. Only output code. Wrap the code like that: ```language\n{code}\n```. Put explanations directly in the code as comments.'
|
||||
|
||||
export const SUPPORTED_LANGUAGES = new Set(Object.keys(PROMPTS))
|
||||
export const SUPPORTED_LANGUAGES = new Set(Object.keys(GEN_CONFIG.prompts))
|
||||
|
||||
let workspace: string | undefined = undefined
|
||||
|
||||
@@ -91,11 +54,10 @@ workspaceStore.subscribe(async (value) => {
|
||||
})
|
||||
|
||||
interface BaseOptions {
|
||||
language: Script.language
|
||||
language: Script.language | 'frontend'
|
||||
}
|
||||
|
||||
interface ScriptGenerationOptions extends BaseOptions {
|
||||
language: Script.language
|
||||
description: string
|
||||
}
|
||||
|
||||
@@ -122,18 +84,16 @@ export async function generateScript(scriptOptions: ScriptGenerationOptions): Pr
|
||||
}
|
||||
})
|
||||
|
||||
let prompt = PROMPTS[scriptOptions.language].replace('{description}', scriptOptions.description)
|
||||
let prompt = GEN_CONFIG.prompts[scriptOptions.language].prompt.replace(
|
||||
'{description}',
|
||||
scriptOptions.description
|
||||
)
|
||||
|
||||
if (
|
||||
[Script.language.DENO, Script.language.BUN, Script.language.NATIVETS].includes(
|
||||
scriptOptions.language
|
||||
)
|
||||
) {
|
||||
if (['deno', 'bun', 'nativets'].includes(scriptOptions.language)) {
|
||||
const resourceTypes = await ResourceService.listResourceType({ workspace })
|
||||
const resourceTypesText = formatResourceTypes(resourceTypes, 'typescript')
|
||||
|
||||
prompt = prompt.replace('{resourceTypes}', resourceTypesText)
|
||||
} else if (scriptOptions.language == Script.language.PYTHON3) {
|
||||
} else if (scriptOptions.language === 'python3') {
|
||||
const resourceTypes = await ResourceService.listResourceType({ workspace })
|
||||
const resourceTypesText = formatResourceTypes(resourceTypes, 'python3')
|
||||
prompt = prompt.replace('{resourceTypes}', resourceTypesText)
|
||||
@@ -145,7 +105,7 @@ export async function generateScript(scriptOptions: ScriptGenerationOptions): Pr
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: SYSTEM_PROMPT
|
||||
content: GEN_CONFIG.system
|
||||
},
|
||||
{
|
||||
role: 'user',
|
||||
@@ -200,18 +160,24 @@ export async function editScript(scriptOptions: EditScriptOptions): Promise<stri
|
||||
}
|
||||
})
|
||||
|
||||
let prompt = EDIT_PROMPT.replace('{lang}', scriptLangToEditorLang(scriptOptions.language))
|
||||
let prompt = EDIT_CONFIG.prompt
|
||||
.replace(
|
||||
'{lang}',
|
||||
scriptOptions.language === 'frontend'
|
||||
? 'javascript'
|
||||
: scriptLangToEditorLang(scriptOptions.language)
|
||||
)
|
||||
.replace('{code}', scriptOptions.selectedCode)
|
||||
.replace('{description}', scriptOptions.description)
|
||||
.replace('{environment}', scriptLangToEnvironment(scriptOptions.language))
|
||||
|
||||
const completion = await openai.chat.completions.create({
|
||||
model: 'gpt-4',
|
||||
max_tokens: 512,
|
||||
max_tokens: 2048,
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: EDIT_SYSTEM_PROMPT
|
||||
content: EDIT_CONFIG.system
|
||||
},
|
||||
{
|
||||
role: 'user',
|
||||
@@ -252,18 +218,24 @@ export async function fixScript(scriptOptions: FixScriptOpions) {
|
||||
}
|
||||
})
|
||||
|
||||
let prompt = FIX_PROMPT.replace('{lang}', scriptLangToEditorLang(scriptOptions.language))
|
||||
let prompt = FIX_CONFIG.prompt
|
||||
.replace(
|
||||
'{lang}',
|
||||
scriptOptions.language === 'frontend'
|
||||
? 'javascript'
|
||||
: scriptLangToEditorLang(scriptOptions.language)
|
||||
)
|
||||
.replace('{code}', scriptOptions.code)
|
||||
.replace('{error}', scriptOptions.error)
|
||||
.replace('{environment}', scriptLangToEnvironment(scriptOptions.language))
|
||||
|
||||
const completion = await openai.chat.completions.create({
|
||||
model: 'gpt-4',
|
||||
max_tokens: 512,
|
||||
max_tokens: 2048,
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: FIX_SYSTEM_PROMPT
|
||||
content: FIX_CONFIG.system
|
||||
},
|
||||
{
|
||||
role: 'user',
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
system: |-
|
||||
You write code as queried by the user. Only output code. Wrap the code like that:
|
||||
```language
|
||||
{code}
|
||||
```
|
||||
Put explanations directly in the code as comments.
|
||||
prompt: |-
|
||||
Here's my environement: {environment}
|
||||
Here's my code:
|
||||
```{lang}
|
||||
{code}
|
||||
```
|
||||
My instructions: {description}
|
||||
@@ -0,0 +1,14 @@
|
||||
system: |-
|
||||
You fix the code shared by the user. Only output code. Wrap the code like that:
|
||||
```language
|
||||
{code}
|
||||
```
|
||||
Put explanations directly in the code as comments.
|
||||
prompt: |-
|
||||
Here's my environement: {environment}
|
||||
Here's my code:
|
||||
```{lang}
|
||||
{code}
|
||||
```
|
||||
I get the following error: {error}
|
||||
Fix it for me.
|
||||
@@ -0,0 +1,49 @@
|
||||
system: |-
|
||||
You write code as queried by the user. Only output code. Wrap the code like that:
|
||||
```language
|
||||
{code}
|
||||
```
|
||||
Put explanations directly in the code as comments.
|
||||
prompts:
|
||||
python3:
|
||||
prompt: |-
|
||||
Write a function in python called "main". The function should {description}. Specify the parameter types. Do not call the main function.
|
||||
You have access to the following resource types, if you need them, you have to define the TypedDict exactly as specified (class name has to be IN LOWERCASE) and add them as parameters: {resourceTypes}
|
||||
If the TypedDict name conflicts with the imported object, rename the imported object NOT THE TYPE.
|
||||
deno:
|
||||
prompt: |-
|
||||
Write a function in typescript called "main". The function should {description}. Specify the parameter types. You are in a Deno environment. You can import deno libraries or you can also import npm libraries like that: "import ... from "npm:{package}";". Export the "main" function like this: "export async function main(...)". Do not call the main function.
|
||||
You have access to the following resource types, if you need them, you have to define the type exactly as specified and add them as parameters: {resourceTypes}
|
||||
If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.
|
||||
go:
|
||||
prompt: |-
|
||||
Write a function in go called "main". The function should {description}. Import the packages you need. The return type of the function has to be ({return_type}, error). The file package has to be "inner".
|
||||
bash:
|
||||
prompt: |-
|
||||
Write bash code that should {description}. Do not include "#!/bin/bash". Arguments are always string and can only be obtained with "var1="$1"", "var2="$2"", etc... You do not need to check if the arguments are present.
|
||||
postgresql:
|
||||
prompt: |-
|
||||
Write SQL code for a PostgreSQL that should {description}. Arguments can be obtained directly in the statement with $1::{type}, $2::{type}, etc... Name the parameters by adding comments before the command like that: -- $1 name1 (one per row, do not include the type)
|
||||
mysql:
|
||||
prompt: |-
|
||||
Write SQL code for MySQL that should {description}. Arguments can be obtained directly in the statement with ?. Name the parameters by adding comments before the command like that: -- ? name1 ({type}) (one per row)
|
||||
nativets:
|
||||
prompt: |-
|
||||
Write a function in typescript called "main". The function should {description}. Specify the parameter types. You should use fetch and are not allowed to import any libraries. Export the "main" function like this: "export async function main(...)". Do not call the main function.
|
||||
You have access to the following resource types, if you need them, you have to define the type exactly as specified and add them as parameters: {resourceTypes}
|
||||
If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.
|
||||
bun:
|
||||
prompt: |-
|
||||
Write a function in typescript called "main". The function should {description}. Specify the parameter types. You are in a Node.js environment. You can import npm libraries. Export the "main" function like this: "export async function main(...)". Do not call the main function.
|
||||
You have access to the following resource types, if you need them, you have to define the type exactly as specified and add them as parameters: {resourceTypes}
|
||||
If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.
|
||||
frontend:
|
||||
prompt: |-
|
||||
Write client-side javascript code that should {description}. You have access to a few helpers:
|
||||
You can access the context object with the ctx global variable.
|
||||
The app state is a store that can be used to store data. You can access and update the state object with the state global variable like this: state.foo = 'bar'
|
||||
You can use the goto function to navigate to a specific URL: goto(path: string, newTab?: boolean)
|
||||
Use the setTab function to manually set the tab of a Tab component: setTab(id: string, index: string)
|
||||
Use the recompute function to recompute a component: recompute(id: string)
|
||||
Use the getAgGrid function to get the ag-grid instance of a table: getAgGrid(id: string)
|
||||
The setValue function is meant to set or force the value of a component: setValue(id: string, value: any).
|
||||
@@ -0,0 +1,25 @@
|
||||
import editObj from './edit.yaml'
|
||||
import fixObj from './fix.yaml'
|
||||
import genObj from './gen.yaml'
|
||||
|
||||
interface CommonConfig {
|
||||
system: string
|
||||
prompt: string
|
||||
}
|
||||
|
||||
interface GenConfig {
|
||||
system: string
|
||||
prompts: {
|
||||
[key: string]: {
|
||||
prompt: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EDIT_CONFIG = editObj as CommonConfig
|
||||
|
||||
const FIX_CONFIG = fixObj as CommonConfig
|
||||
|
||||
const GEN_CONFIG = genObj as GenConfig
|
||||
|
||||
export { EDIT_CONFIG, FIX_CONFIG, GEN_CONFIG }
|
||||
@@ -32,6 +32,7 @@
|
||||
import FlowModuleMock from './FlowModuleMock.svelte'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import { SecondsInput } from '$lib/components/common'
|
||||
import DiffEditor from '$lib/components/DiffEditor.svelte'
|
||||
|
||||
const { selectedId, previewArgs, flowStateStore, flowStore, saveDraft } =
|
||||
getContext<FlowEditorContext>('FlowEditorContext')
|
||||
@@ -43,6 +44,7 @@
|
||||
export let previousModule: FlowModule | undefined
|
||||
|
||||
let editor: Editor
|
||||
let diffEditor: DiffEditor
|
||||
let modulePreview: ModulePreview
|
||||
let websocketAlive = {
|
||||
pyright: false,
|
||||
@@ -174,6 +176,7 @@
|
||||
<EditorBar
|
||||
{validCode}
|
||||
{editor}
|
||||
{diffEditor}
|
||||
lang={flowModule.value['language'] ?? 'deno'}
|
||||
{websocketAlive}
|
||||
iconOnly={width < 850}
|
||||
@@ -222,6 +225,12 @@
|
||||
}}
|
||||
fixedOverflowWidgets={true}
|
||||
/>
|
||||
<DiffEditor
|
||||
bind:this={diffEditor}
|
||||
automaticLayout
|
||||
fixedOverflowWidgets
|
||||
class="hidden h-full"
|
||||
/>
|
||||
{/key}
|
||||
{:else if flowModule.value.type === 'script'}
|
||||
<div class="border-t border-gray-200">
|
||||
@@ -260,6 +269,9 @@
|
||||
pickableProperties={stepPropPicker.pickableProperties}
|
||||
bind:this={modulePreview}
|
||||
mod={flowModule}
|
||||
{editor}
|
||||
{diffEditor}
|
||||
lang={flowModule.value['language'] ?? 'deno'}
|
||||
schema={$flowStateStore[$selectedId]?.schema ?? {}}
|
||||
/>
|
||||
{:else if selected === 'advanced'}
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
selectAll,
|
||||
pointer
|
||||
}
|
||||
|
||||
let d3Zoom = determineD3Instance(
|
||||
boundary,
|
||||
d3,
|
||||
@@ -89,6 +90,7 @@
|
||||
|
||||
d3.select(`#zoom_in_${canvasId}`).on('click', function () {
|
||||
try {
|
||||
// @ts-ignore
|
||||
d3Zoom.scaleBy(nodes.transition().duration(250), 1.4)
|
||||
} catch (e) {
|
||||
console.log('error', e)
|
||||
@@ -96,6 +98,7 @@
|
||||
})
|
||||
d3.select(`#zoom_out_${canvasId}`).on('click', function () {
|
||||
try {
|
||||
// @ts-ignore
|
||||
d3Zoom.scaleBy(nodes.transition().duration(250), 0.714)
|
||||
} catch (e) {
|
||||
console.log('error', e)
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
"paths": {
|
||||
"$lib": ["src/lib"],
|
||||
"$lib/*": ["src/lib/*"]
|
||||
}
|
||||
},
|
||||
"types": ["@modyfi/vite-plugin-yaml/modules"]
|
||||
},
|
||||
"include": ["src/**/*.js", "src/**/*.ts", "src/**/*.d.ts", "src/**/*.svelte"],
|
||||
"extends": "./.svelte-kit/tsconfig.json"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { sveltekit } from '@sveltejs/kit/vite'
|
||||
import { readFileSync } from 'fs'
|
||||
import { fileURLToPath } from 'url'
|
||||
import ViteYaml from '@modyfi/vite-plugin-yaml'
|
||||
|
||||
const file = fileURLToPath(new URL('package.json', import.meta.url))
|
||||
const json = readFileSync(file, 'utf8')
|
||||
@@ -31,7 +32,7 @@ const config = {
|
||||
preview: {
|
||||
port: 3000
|
||||
},
|
||||
plugins: [sveltekit()],
|
||||
plugins: [sveltekit(), ViteYaml()],
|
||||
define: {
|
||||
__pkg__: version
|
||||
},
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.venv
|
||||
.env
|
||||
**/__pycache__
|
||||
@@ -0,0 +1,42 @@
|
||||
# Test sample queries of the AI feature
|
||||
|
||||
## Setup
|
||||
|
||||
Create a virtual environment `python -m venv .venv`, activate it `source .venv/bin/activate` and install the requirements `pip install -r requirements.txt`. Put your `OPENAI_API_KEY` in `.env`.
|
||||
|
||||
## Run
|
||||
|
||||
Run the script `python src/gen_samples.py` and check the results in `sample_answers.yaml`.
|
||||
|
||||
## Add queries
|
||||
|
||||
You can add more queries in `sample_queries.yaml`. There are three types of queries:
|
||||
|
||||
### Generate code from a prompt
|
||||
|
||||
```yaml
|
||||
- type: gen
|
||||
description: hello world
|
||||
lang: python3
|
||||
```
|
||||
|
||||
### Modifiy code according to a prompt
|
||||
|
||||
```yaml
|
||||
- type: edit
|
||||
description: comment
|
||||
lang: python3
|
||||
code: |-
|
||||
print("hello world")
|
||||
```
|
||||
|
||||
### Fix code given an error
|
||||
|
||||
```yaml
|
||||
- type: fix
|
||||
lang: python3
|
||||
code: |-
|
||||
def main():
|
||||
return 3 / 0
|
||||
error: division by zero
|
||||
```
|
||||
@@ -0,0 +1,4 @@
|
||||
openai==0.27.8
|
||||
python-dotenv==1.0.0
|
||||
pyyaml==6.0
|
||||
tqdm==4.65.0
|
||||
@@ -0,0 +1,312 @@
|
||||
- answer: |-
|
||||
```python
|
||||
import psycopg2
|
||||
from typing import TypedDict
|
||||
|
||||
class postgresql(TypedDict):
|
||||
host: str
|
||||
port: int
|
||||
user: str
|
||||
dbname: str
|
||||
sslmode: str
|
||||
password: str
|
||||
|
||||
def main(postgres_config: postgresql):
|
||||
# Connect to the PostgreSQL server
|
||||
conn = psycopg2.connect(
|
||||
host=postgres_config['host'],
|
||||
port=postgres_config['port'],
|
||||
user=postgres_config['user'],
|
||||
password=postgres_config['password'],
|
||||
dbname=postgres_config['dbname'],
|
||||
sslmode=postgres_config['sslmode']
|
||||
)
|
||||
|
||||
# Create a cursor object
|
||||
cur = conn.cursor()
|
||||
|
||||
# Execute a query
|
||||
cur.execute("SELECT * FROM orders")
|
||||
|
||||
# Fetch all the rows
|
||||
rows = cur.fetchall()
|
||||
|
||||
# Print all the rows
|
||||
for row in rows:
|
||||
print(row)
|
||||
|
||||
# Close the cursor and connection
|
||||
cur.close()
|
||||
conn.close()
|
||||
```
|
||||
description: Connect to postgres and list the rows in the orders table
|
||||
lang: python3
|
||||
type: gen
|
||||
- answer: |-
|
||||
Sure, here's the corrected code. I've added a check to ensure that the number passed to the function is not zero to prevent a division by zero error.
|
||||
|
||||
```python
|
||||
def main(num: int) -> int:
|
||||
if num == 0:
|
||||
raise ValueError("The input number should not be zero") # raise an error if num is zero
|
||||
return 3 / num
|
||||
```
|
||||
This code will raise a ValueError if the input number is zero.
|
||||
code: |-
|
||||
def main(num: int) -> int:
|
||||
return 3 / num
|
||||
error: division by zero
|
||||
lang: python3
|
||||
type: fix
|
||||
- answer: |-
|
||||
Sure, here's your code with comments:
|
||||
|
||||
```python
|
||||
# This is a Python function that takes an integer as input.
|
||||
def main(num: int) -> int:
|
||||
# The function divides the input number by 16.
|
||||
# The result of this division is then returned by the function.
|
||||
return num / 16
|
||||
```
|
||||
code: |-
|
||||
def main(num: int) -> int:
|
||||
return num / 16
|
||||
description: Comment my code
|
||||
lang: python3
|
||||
type: edit
|
||||
- answer: |-
|
||||
```go
|
||||
package inner
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Function to divide a number by 16
|
||||
func main(num float64) (float64, error) {
|
||||
if num == 0 {
|
||||
return 0, errors.New("Division by zero is not allowed")
|
||||
}
|
||||
|
||||
result := num / 16
|
||||
return result, nil
|
||||
}
|
||||
```
|
||||
In this code, we define a function called `main` that takes a float64 number as an input. It then divides the number by 16 and returns the result. If the number is 0, it returns an error.
|
||||
description: Divide a number by 16
|
||||
lang: go
|
||||
type: gen
|
||||
- answer: |-
|
||||
```typescript
|
||||
import { toWords } from "npm:number-to-words"; // Importing the "number-to-words" npm package.
|
||||
|
||||
export async function main(number: number): Promise<string> {
|
||||
// Convert the number to words.
|
||||
const words = toWords(number);
|
||||
|
||||
// Return the words.
|
||||
return words;
|
||||
}
|
||||
```
|
||||
In this function, we are using the "number-to-words" npm package to convert a number to words. The function takes a number as an argument and returns a Promise that resolves to a string. The string is the word representation of the number.
|
||||
description: Convert a number to a word
|
||||
lang: deno
|
||||
type: gen
|
||||
- answer: |-
|
||||
```typescript
|
||||
// Importing the required libraries
|
||||
import { Client } from "npm:https://deno.land/x/postgres@v0.13.0/mod.ts";
|
||||
|
||||
type Postgresql = {
|
||||
host: string,
|
||||
port: number,
|
||||
user: string,
|
||||
dbname: string,
|
||||
sslmode: string,
|
||||
password: string
|
||||
}
|
||||
|
||||
// Exporting the main function
|
||||
export async function main(postgres: Postgresql) {
|
||||
// Creating a new client with the provided configuration
|
||||
const client = new Client({
|
||||
hostname: postgres.host,
|
||||
port: postgres.port,
|
||||
user: postgres.user,
|
||||
password: postgres.password,
|
||||
database: postgres.dbname,
|
||||
tls: {
|
||||
enforce: postgres.sslmode === "require",
|
||||
},
|
||||
});
|
||||
|
||||
// Connecting to the database
|
||||
await client.connect();
|
||||
|
||||
// Querying the "orders" table
|
||||
const result = await client.queryArray("SELECT * FROM orders;");
|
||||
|
||||
// Closing the connection
|
||||
await client.end();
|
||||
|
||||
// Returning the rows of the "orders" table
|
||||
return result.rows;
|
||||
}
|
||||
```
|
||||
In this function, we first import the `Client` class from the `postgres` library. We then define a function `main` that takes a `Postgresql` object as argument. This object contains the information needed to connect to the PostgreSQL database.
|
||||
|
||||
In the function, we first create a new `Client` instance with the provided configuration. We then connect to the database, query the "orders" table, and close the connection. Finally, we return the rows of the "orders" table.
|
||||
description: Connect to postgres and list the rows in the orders table
|
||||
lang: deno
|
||||
type: gen
|
||||
- answer: |-
|
||||
```typescript
|
||||
// Importing the npm library "number-to-words" to convert numbers to words
|
||||
import * as numberToWords from 'number-to-words';
|
||||
|
||||
type Airtable = {
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
type AirtableTable = {
|
||||
baseId: string,
|
||||
tableName: string
|
||||
}
|
||||
|
||||
// ... all the other types here ...
|
||||
|
||||
type Toggl = {
|
||||
token: string
|
||||
}
|
||||
|
||||
// Defining the main function
|
||||
export async function main(number: number): Promise<string> {
|
||||
// Converting the number to a word using the numberToWords library
|
||||
const word = numberToWords.toWords(number);
|
||||
|
||||
// Returning the word
|
||||
return word;
|
||||
}
|
||||
```
|
||||
Note: This code assumes that you have installed the `number-to-words` npm package in your project. If not, you can install it by running `npm install --save number-to-words` in your project directory.
|
||||
description: Convert a number to a word
|
||||
lang: bun
|
||||
type: gen
|
||||
- answer: |-
|
||||
```sql
|
||||
-- $1::text as name
|
||||
-- $2::text as email
|
||||
INSERT INTO users (name, email)
|
||||
VALUES ($1::text, $2::text);
|
||||
```
|
||||
description: Insert an email and a name in the users table
|
||||
lang: postgresql
|
||||
type: gen
|
||||
- answer: |-
|
||||
```sql
|
||||
-- ? email (VARCHAR)
|
||||
-- ? name (VARCHAR)
|
||||
INSERT INTO users (email, name) VALUES (?, ?)
|
||||
```
|
||||
description: Insert an email and a name in the users table
|
||||
lang: mysql
|
||||
type: gen
|
||||
- answer: |-
|
||||
```bash
|
||||
var1="$1" # Get the first argument
|
||||
|
||||
result=$(echo "scale=2; $var1 / 16" | bc) # Divide the number by 16 using bc command. Scale is used to get the decimal values up to 2 places
|
||||
|
||||
echo $result # Print the result
|
||||
```
|
||||
description: Divide a number by 16
|
||||
lang: bash
|
||||
type: gen
|
||||
- answer: |-
|
||||
Here is a simple Dockerfile for a Python application. It assumes that your application is using Flask and Gunicorn, but you can replace these with your actual dependencies.
|
||||
|
||||
```dockerfile
|
||||
# Use an official Python runtime as a parent image
|
||||
FROM python:3.7-slim
|
||||
|
||||
# Set the working directory in the container to /app
|
||||
WORKDIR /app
|
||||
|
||||
# Add the current directory contents into the container at /app
|
||||
ADD . /app
|
||||
|
||||
# Install any needed packages specified in requirements.txt
|
||||
RUN pip install --trusted-host pypi.python.org -r requirements.txt
|
||||
|
||||
# Make port 80 available to the world outside this container
|
||||
EXPOSE 80
|
||||
|
||||
# Define environment variable
|
||||
ENV NAME World
|
||||
|
||||
# Run app.py when the container launches
|
||||
CMD ["gunicorn", "app:app"]
|
||||
```
|
||||
|
||||
This Dockerfile does the following:
|
||||
|
||||
- `FROM python:3.7-slim` starts with the 3.7-slim Python image.
|
||||
- `WORKDIR /app` sets the working directory inside the container to /app.
|
||||
- `ADD . /app` copies the current directory (i.e., the directory containing the Dockerfile) into the container at /app.
|
||||
- `RUN pip install --trusted-host pypi.python.org -r requirements.txt` installs the Python dependencies.
|
||||
- `EXPOSE 80` makes port 80 available outside the container.
|
||||
- `ENV NAME World` sets an environment variable.
|
||||
- `CMD ["gunicorn", "app:app"]` runs your application with Gunicorn when the container starts.
|
||||
description: Write a docker image for a python app
|
||||
lang: bash
|
||||
type: gen
|
||||
- answer: |-
|
||||
```typescript
|
||||
// Define the Github type
|
||||
type Github = {
|
||||
token: string
|
||||
}
|
||||
|
||||
// Define the main function
|
||||
export async function main(github: Github, owner: string, repo: string): Promise<number> {
|
||||
// Define the url for the Github API
|
||||
const url = `https://api.github.com/repos/${owner}/${repo}`;
|
||||
|
||||
// Define the headers for the request
|
||||
const headers = {
|
||||
'Authorization': `token ${github.token}`,
|
||||
'Accept': 'application/vnd.github.v3+json'
|
||||
};
|
||||
|
||||
// Fetch the data from the Github API
|
||||
const response = await fetch(url, { headers });
|
||||
|
||||
// Check if the response is ok
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
// Parse the response as JSON
|
||||
const data = await response.json();
|
||||
|
||||
// Return the number of stars
|
||||
return data.stargazers_count;
|
||||
}
|
||||
```
|
||||
This function takes a Github object and the owner and repo as strings. It constructs the URL for the Github API and defines the headers for the request. It then fetches the data from the Github API and checks if the response is ok. If it is, it parses the response as JSON and returns the number of stars. If the response is not ok, it throws an error.
|
||||
description: Query the github api and return the number of stars of a repo
|
||||
lang: nativets
|
||||
type: gen
|
||||
- answer: |-
|
||||
```javascript
|
||||
// Access the email from the context object
|
||||
let email = ctx.email;
|
||||
|
||||
// Set the value of the input with id 'my_field' to the email
|
||||
setValue('my_field', email);
|
||||
```
|
||||
description: set the value of the input with id 'my_field' to the context variable
|
||||
email
|
||||
lang: frontend
|
||||
type: gen
|
||||
@@ -0,0 +1,45 @@
|
||||
- lang: python3
|
||||
type: gen
|
||||
description: Connect to postgres and list the rows in the orders table
|
||||
- lang: python3
|
||||
type: fix
|
||||
code: |-
|
||||
def main(num: int) -> int:
|
||||
return 3 / num
|
||||
error: division by zero
|
||||
- lang: python3
|
||||
type: edit
|
||||
code: |-
|
||||
def main(num: int) -> int:
|
||||
return num / 16
|
||||
description: Comment my code
|
||||
- lang: go
|
||||
type: gen
|
||||
description: Divide a number by 16
|
||||
- lang: deno
|
||||
type: gen
|
||||
description: Convert a number to a word
|
||||
- lang: deno
|
||||
type: gen
|
||||
description: Connect to postgres and list the rows in the orders table
|
||||
- lang: bun
|
||||
type: gen
|
||||
description: Convert a number to a word
|
||||
- lang: postgresql
|
||||
type: gen
|
||||
description: Insert an email and a name in the users table
|
||||
- lang: mysql
|
||||
type: gen
|
||||
description: Insert an email and a name in the users table
|
||||
- lang: bash
|
||||
type: gen
|
||||
description: Divide a number by 16
|
||||
- lang: bash
|
||||
type: gen
|
||||
description: Write a docker image for a python app
|
||||
- lang: nativets
|
||||
type: gen
|
||||
description: Query the github api and return the number of stars of a repo
|
||||
- lang: frontend
|
||||
type: gen
|
||||
description: set the value of the input with id 'my_field' to the context variable email
|
||||
@@ -0,0 +1,184 @@
|
||||
import argparse
|
||||
import yaml
|
||||
from dotenv import load_dotenv
|
||||
from tqdm import tqdm
|
||||
from resources import RESOURCE_TYPES
|
||||
|
||||
load_dotenv()
|
||||
|
||||
import openai
|
||||
|
||||
import re
|
||||
|
||||
|
||||
from typing import TypedDict, Tuple
|
||||
|
||||
|
||||
class Literal(str):
|
||||
pass
|
||||
|
||||
|
||||
def literal_presenter(dumper, data):
|
||||
return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|")
|
||||
|
||||
|
||||
yaml.add_representer(Literal, literal_presenter)
|
||||
|
||||
|
||||
class GenPrompt(TypedDict):
|
||||
prompt: str
|
||||
|
||||
|
||||
class GenConfig(TypedDict):
|
||||
prompts: dict[str, GenPrompt]
|
||||
system: str
|
||||
|
||||
|
||||
class CommonConfig(TypedDict):
|
||||
system: str
|
||||
prompt: str
|
||||
|
||||
|
||||
class Query(TypedDict):
|
||||
description: str
|
||||
type: str
|
||||
lang: str
|
||||
code: str
|
||||
error: str
|
||||
|
||||
|
||||
def scriptLangToCodeLang(lang: str):
|
||||
if lang in ["deno", "bun", "nativets"]:
|
||||
return "typescript"
|
||||
elif lang in ["postgresql", "mysql"]:
|
||||
return "sql"
|
||||
elif lang == "python3":
|
||||
return "python"
|
||||
elif lang == "bash":
|
||||
return "shell"
|
||||
elif lang == "frontend":
|
||||
return "javascript"
|
||||
else:
|
||||
return lang
|
||||
|
||||
|
||||
def scriptLangToEnvironment(lang: str):
|
||||
if lang == "deno":
|
||||
return "typescript in a deno running environment"
|
||||
elif lang == "bun":
|
||||
return "typescript in a node.js running environment"
|
||||
elif lang == "nativets":
|
||||
return "typescript where you should use fetch and are not allowed to import any libraries"
|
||||
elif lang == "frontend":
|
||||
return "client-side javascript"
|
||||
else:
|
||||
return lang
|
||||
|
||||
|
||||
def get_prompts(prompts_path: str) -> Tuple[GenConfig, CommonConfig, CommonConfig]:
|
||||
GEN_CONFIG = None
|
||||
EDIT_CONFIG = None
|
||||
FIX_CONFIG = None
|
||||
with open(prompts_path + "/gen.yaml") as f:
|
||||
GEN_CONFIG = yaml.safe_load(f)
|
||||
with open(prompts_path + "/edit.yaml") as f:
|
||||
EDIT_CONFIG = yaml.safe_load(f)
|
||||
with open(prompts_path + "/fix.yaml") as f:
|
||||
FIX_CONFIG = yaml.safe_load(f)
|
||||
return GEN_CONFIG, EDIT_CONFIG, FIX_CONFIG
|
||||
|
||||
|
||||
def get_queries(queries_path: str) -> list[Query]:
|
||||
with open(queries_path) as f:
|
||||
return yaml.safe_load(f)
|
||||
|
||||
|
||||
def prepare_prompt(
|
||||
query: Query,
|
||||
GEN_CONFIG: GenConfig,
|
||||
EDIT_CONFIG: CommonConfig,
|
||||
FIX_CONFIG: CommonConfig,
|
||||
):
|
||||
system = ""
|
||||
prompt = ""
|
||||
if query["type"] == "gen":
|
||||
system = GEN_CONFIG["system"]
|
||||
prompt = GEN_CONFIG["prompts"][query["lang"]]["prompt"]
|
||||
prompt = prompt.replace("{description}", query["description"])
|
||||
if query["lang"] in ["deno", "bun", "nativets"]:
|
||||
prompt = prompt.replace("{resourceTypes}", RESOURCE_TYPES["typescript"])
|
||||
elif query["lang"] in ["python3"]:
|
||||
prompt = prompt.replace("{resourceTypes}", RESOURCE_TYPES["python"])
|
||||
elif query["type"] == "edit":
|
||||
system = EDIT_CONFIG["system"]
|
||||
prompt = EDIT_CONFIG["prompt"]
|
||||
lang = scriptLangToCodeLang(query["lang"])
|
||||
environment = scriptLangToEnvironment(query["lang"])
|
||||
prompt = (
|
||||
prompt.replace("{description}", query["description"])
|
||||
.replace("{lang}", lang)
|
||||
.replace("{environment}", environment)
|
||||
.replace("{code}", query["code"])
|
||||
)
|
||||
elif query["type"] == "fix":
|
||||
system = FIX_CONFIG["system"]
|
||||
prompt = FIX_CONFIG["prompt"]
|
||||
lang = scriptLangToCodeLang(query["lang"])
|
||||
environment = scriptLangToEnvironment(query["lang"])
|
||||
prompt = (
|
||||
prompt.replace("{lang}", lang)
|
||||
.replace("{environment}", environment)
|
||||
.replace("{error}", query["error"])
|
||||
.replace("{code}", query["code"])
|
||||
)
|
||||
|
||||
return system, prompt
|
||||
|
||||
|
||||
def format_answer(answer: str):
|
||||
return re.sub("[^\\S\n]+\n", "\n", answer).replace("\t", " ")
|
||||
|
||||
|
||||
def gen_samples(queries_path: str, answers_path: str, prompts_path: str):
|
||||
GEN_CONFIG, EDIT_CONFIG, FIX_CONFIG = get_prompts(prompts_path)
|
||||
|
||||
queries = get_queries(queries_path)
|
||||
|
||||
answers = []
|
||||
for query in tqdm(queries):
|
||||
system, prompt = prepare_prompt(query, GEN_CONFIG, EDIT_CONFIG, FIX_CONFIG)
|
||||
chat_completion = openai.ChatCompletion.create(
|
||||
model="gpt-4",
|
||||
messages=[
|
||||
{"role": "system", "content": system},
|
||||
{"role": "user", "content": prompt},
|
||||
],
|
||||
temperature=0.5,
|
||||
max_tokens=2048,
|
||||
)
|
||||
|
||||
answer = {
|
||||
**query,
|
||||
"answer": Literal(format_answer(chat_completion["choices"][0]["message"]["content"])), # type: ignore
|
||||
}
|
||||
|
||||
if "code" in query:
|
||||
answer["code"] = Literal(query["code"])
|
||||
|
||||
answers.append(answer)
|
||||
|
||||
with open(answers_path, "w") as f:
|
||||
yaml.dump(answers, f)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Process some integers.")
|
||||
parser.add_argument("--queries_path", type=str, default="./sample_queries.yaml")
|
||||
parser.add_argument("--answers_path", type=str, default="./sample_answers.yaml")
|
||||
parser.add_argument(
|
||||
"--prompts_path",
|
||||
type=str,
|
||||
default="../frontend/src/lib/components/codeGen/prompts",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
gen_samples(args.queries_path, args.answers_path, args.prompts_path)
|
||||
@@ -0,0 +1,493 @@
|
||||
RESOURCE_TYPES = {
|
||||
"typescript": """type Airtable = {
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
type AirtableTable = {
|
||||
baseId: string,
|
||||
tableName: string
|
||||
}
|
||||
|
||||
type Appwrite = {
|
||||
key: string,
|
||||
project: string,
|
||||
endpoint: string,
|
||||
self_signed: boolean
|
||||
}
|
||||
|
||||
type Aws = {
|
||||
region: string,
|
||||
awsAccessKeyId: string,
|
||||
awsSecretAccessKey: string
|
||||
}
|
||||
|
||||
type Azure = {
|
||||
azureClientId: string,
|
||||
azureTenantId: string,
|
||||
azureClientSecret: string
|
||||
}
|
||||
|
||||
type Clickhouse = {
|
||||
host: string,
|
||||
password: string,
|
||||
username: string
|
||||
}
|
||||
|
||||
type CMyResourceType = {
|
||||
name: string
|
||||
}
|
||||
|
||||
type CSolarFlar = {
|
||||
a: number,
|
||||
b: number,
|
||||
c: boolean,
|
||||
d: string,
|
||||
e: any,
|
||||
f: any[],
|
||||
g: any,
|
||||
h: any
|
||||
}
|
||||
|
||||
type Datadog = {
|
||||
apiKey: string,
|
||||
appKey: string,
|
||||
apiBase: string
|
||||
}
|
||||
|
||||
type DiscordBotConfiguration = {
|
||||
public_key: string,
|
||||
application_id: string
|
||||
}
|
||||
|
||||
type DiscordWebhook = {
|
||||
webhook_url: string
|
||||
}
|
||||
|
||||
type Dynatrace = {
|
||||
accessToken: string,
|
||||
environmentId: string,
|
||||
environmentUrl: string
|
||||
}
|
||||
|
||||
type Faunadb = {
|
||||
region: string,
|
||||
secret: string
|
||||
}
|
||||
|
||||
type Firebase = {
|
||||
appId: string,
|
||||
apiKey: string,
|
||||
projectId: string,
|
||||
authDomain: string,
|
||||
measurementId: string,
|
||||
storageBucket: string,
|
||||
messagingSenderId: string
|
||||
}
|
||||
|
||||
type Funkwhale = {
|
||||
token: string,
|
||||
baseUrl: string
|
||||
}
|
||||
|
||||
type Gcal = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type GcpServiceAccount = {
|
||||
type: string,
|
||||
auth_uri: string,
|
||||
client_id: string,
|
||||
token_uri: string,
|
||||
project_id: string,
|
||||
private_key: string,
|
||||
client_email: string,
|
||||
private_key_id: string,
|
||||
client_x509_cert_url: string,
|
||||
auth_provider_x509_cert_url: string
|
||||
}
|
||||
|
||||
type Gdrive = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type Github = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type Gitlab = {
|
||||
token: string,
|
||||
baseUrl: string
|
||||
}
|
||||
|
||||
type Gmail = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type Gsheets = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type Hubspot = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type Ipinfo = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type Linkding = {
|
||||
token: string,
|
||||
baseUrl: string
|
||||
}
|
||||
|
||||
type Linkedin = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type Mailchimp = {
|
||||
server: string,
|
||||
api_key: string
|
||||
}
|
||||
|
||||
type Mailgun = {
|
||||
api_key: string
|
||||
}
|
||||
|
||||
type Mastodon = {
|
||||
token: string,
|
||||
baseUrl: string
|
||||
}
|
||||
|
||||
type Matrix = {
|
||||
token: string,
|
||||
baseUrl: string
|
||||
}
|
||||
|
||||
type Mongodb = {
|
||||
db: string,
|
||||
tls: boolean,
|
||||
servers: any,
|
||||
credential: any
|
||||
}
|
||||
|
||||
type MongodbRest = {
|
||||
api_key: string,
|
||||
endpoint: string
|
||||
}
|
||||
|
||||
type Mysql = {
|
||||
host: string,
|
||||
port: number,
|
||||
user: string,
|
||||
database: string,
|
||||
password: string
|
||||
}
|
||||
|
||||
type Nocodb = {
|
||||
table: string,
|
||||
apiUrl: string,
|
||||
xc_token: string,
|
||||
workspace: string
|
||||
}
|
||||
|
||||
type Notion = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type Openai = {
|
||||
api_key: string,
|
||||
organization_id: string
|
||||
}
|
||||
|
||||
type Pinecone = {
|
||||
apiKey: string,
|
||||
environment: string
|
||||
}
|
||||
|
||||
type Postgresql = {
|
||||
host: string,
|
||||
port: number,
|
||||
user: string,
|
||||
dbname: string,
|
||||
sslmode: string,
|
||||
password: string
|
||||
}
|
||||
|
||||
type Rss = {
|
||||
url: string
|
||||
}
|
||||
|
||||
type S3 = {
|
||||
port: number,
|
||||
bucket: string,
|
||||
region: string,
|
||||
useSSL: boolean,
|
||||
endPoint: string,
|
||||
accessKey: string,
|
||||
pathStyle: boolean,
|
||||
secretKey: string
|
||||
}
|
||||
|
||||
type Sendgrid = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type Slack = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type Smtp = {
|
||||
host: string,
|
||||
port: number,
|
||||
user: string,
|
||||
password: string
|
||||
}
|
||||
|
||||
type Square = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type Stripe = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type Supabase = {
|
||||
key: string,
|
||||
url: string
|
||||
}
|
||||
|
||||
type Surrealdb = {
|
||||
url: string,
|
||||
token: string
|
||||
}
|
||||
|
||||
type Telegram = {
|
||||
token: string
|
||||
}
|
||||
|
||||
type Toggl = {
|
||||
token: string
|
||||
}
|
||||
""",
|
||||
"python": """class airtable(TypedDict):
|
||||
apiKey: str
|
||||
|
||||
class airtable_table(TypedDict):
|
||||
baseId: str
|
||||
tableName: str
|
||||
|
||||
class appwrite(TypedDict):
|
||||
key: str
|
||||
project: str
|
||||
endpoint: str
|
||||
self_signed: bool
|
||||
|
||||
class aws(TypedDict):
|
||||
region: str
|
||||
awsAccessKeyId: str
|
||||
awsSecretAccessKey: str
|
||||
|
||||
class azure(TypedDict):
|
||||
azureClientId: str
|
||||
azureTenantId: str
|
||||
azureClientSecret: str
|
||||
|
||||
class clickhouse(TypedDict):
|
||||
host: str
|
||||
password: str
|
||||
username: str
|
||||
|
||||
class c_my_resource_type(TypedDict):
|
||||
name: str
|
||||
|
||||
class c_solar_flar(TypedDict):
|
||||
a: int
|
||||
b: float
|
||||
c: bool
|
||||
d: str
|
||||
e: dict
|
||||
f: list
|
||||
g: dict
|
||||
h: dict
|
||||
|
||||
class datadog(TypedDict):
|
||||
apiKey: str
|
||||
appKey: str
|
||||
apiBase: str
|
||||
|
||||
class discord_bot_configuration(TypedDict):
|
||||
public_key: str
|
||||
application_id: str
|
||||
|
||||
class discord_webhook(TypedDict):
|
||||
webhook_url: str
|
||||
|
||||
class dynatrace(TypedDict):
|
||||
accessToken: str
|
||||
environmentId: str
|
||||
environmentUrl: str
|
||||
|
||||
class faunadb(TypedDict):
|
||||
region: str
|
||||
secret: str
|
||||
|
||||
class firebase(TypedDict):
|
||||
appId: str
|
||||
apiKey: str
|
||||
projectId: str
|
||||
authDomain: str
|
||||
measurementId: str
|
||||
storageBucket: str
|
||||
messagingSenderId: str
|
||||
|
||||
class funkwhale(TypedDict):
|
||||
token: str
|
||||
baseUrl: str
|
||||
|
||||
class gcal(TypedDict):
|
||||
token: str
|
||||
|
||||
class gcp_service_account(TypedDict):
|
||||
type: str
|
||||
auth_uri: str
|
||||
client_id: str
|
||||
token_uri: str
|
||||
project_id: str
|
||||
private_key: str
|
||||
client_email: str
|
||||
private_key_id: str
|
||||
client_x509_cert_url: str
|
||||
auth_provider_x509_cert_url: str
|
||||
|
||||
class gdrive(TypedDict):
|
||||
token: str
|
||||
|
||||
class github(TypedDict):
|
||||
token: str
|
||||
|
||||
class gitlab(TypedDict):
|
||||
token: str
|
||||
baseUrl: str
|
||||
|
||||
class gmail(TypedDict):
|
||||
token: str
|
||||
|
||||
class gsheets(TypedDict):
|
||||
token: str
|
||||
|
||||
class hubspot(TypedDict):
|
||||
token: str
|
||||
|
||||
class ipinfo(TypedDict):
|
||||
token: str
|
||||
|
||||
class linkding(TypedDict):
|
||||
token: str
|
||||
baseUrl: str
|
||||
|
||||
class linkedin(TypedDict):
|
||||
token: str
|
||||
|
||||
class mailchimp(TypedDict):
|
||||
server: str
|
||||
api_key: str
|
||||
|
||||
class mailgun(TypedDict):
|
||||
api_key: str
|
||||
|
||||
class mastodon(TypedDict):
|
||||
token: str
|
||||
baseUrl: str
|
||||
|
||||
class matrix(TypedDict):
|
||||
token: str
|
||||
baseUrl: str
|
||||
|
||||
class mongodb(TypedDict):
|
||||
db: str
|
||||
tls: bool
|
||||
servers: dict
|
||||
credential: dict
|
||||
|
||||
class mongodb_rest(TypedDict):
|
||||
api_key: str
|
||||
endpoint: str
|
||||
|
||||
class mysql(TypedDict):
|
||||
host: str
|
||||
port: float
|
||||
user: str
|
||||
database: str
|
||||
password: str
|
||||
|
||||
class nocodb(TypedDict):
|
||||
table: str
|
||||
apiUrl: str
|
||||
xc_token: str
|
||||
workspace: str
|
||||
|
||||
class notion(TypedDict):
|
||||
token: str
|
||||
|
||||
class openai(TypedDict):
|
||||
api_key: str
|
||||
organization_id: str
|
||||
|
||||
class pinecone(TypedDict):
|
||||
apiKey: str
|
||||
environment: str
|
||||
|
||||
class postgresql(TypedDict):
|
||||
host: str
|
||||
port: int
|
||||
user: str
|
||||
dbname: str
|
||||
sslmode: str
|
||||
password: str
|
||||
|
||||
class rss(TypedDict):
|
||||
url: str
|
||||
|
||||
class s3(TypedDict):
|
||||
port: float
|
||||
bucket: str
|
||||
region: str
|
||||
useSSL: bool
|
||||
endPoint: str
|
||||
accessKey: str
|
||||
pathStyle: bool
|
||||
secretKey: str
|
||||
|
||||
class sendgrid(TypedDict):
|
||||
token: str
|
||||
|
||||
class slack(TypedDict):
|
||||
token: str
|
||||
|
||||
class smtp(TypedDict):
|
||||
host: str
|
||||
port: int
|
||||
user: str
|
||||
password: str
|
||||
|
||||
class square(TypedDict):
|
||||
token: str
|
||||
|
||||
class stripe(TypedDict):
|
||||
token: str
|
||||
|
||||
class supabase(TypedDict):
|
||||
key: str
|
||||
url: str
|
||||
|
||||
class surrealdb(TypedDict):
|
||||
url: str
|
||||
token: str
|
||||
|
||||
class telegram(TypedDict):
|
||||
token: str
|
||||
|
||||
class toggl(TypedDict):
|
||||
token: str
|
||||
""",
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
3.10.4
|
||||
Reference in New Issue
Block a user