mirror of
https://github.com/ianarawjo/ChainForge.git
synced 2025-03-14 08:16:37 +00:00
Better edges, ReactFlow v11, AlephAlpha integration, better .gitignores (#139)
* add aleph alpha to installg guide description * add aleph alpha to settings to add key * add settings for alephalpha * add aleph alpha to models * add aleph alpha api key to keymap * no visible changes, removed console.log * current working copy * added settings for aleph alpha, added test, working api request * removed console log * added static build with Aleph Alpha integration * added static build with Aleph Alpha integration * Corrected from ALEPH_ALPHA_KEY to ALEPH_ALPHA_API_KEY * add additional settings requested * merge conflicts * add build to gitignore, best practice, reduces conflicts * remove empty lines * Delete chainforge/react-server/build directory build directory should not be in remote * remove unnecessary changes * Update backend.ts * ... * fixed import * add aleph alpha to store, remove available llms from modelsettings, remove double palm key input from globalsettings * Update to ReactFlow v11 * Add remove button to edge on hover * Quality of life improvements (#133) * Quality of life improvements for node and python * Pinned minor version for mantine modules * Updated package-lock.json * Added .gitignore to react-server * Updated .gitignore to python module --------- Co-authored-by: ianarawjo <fatso784@gmail.com> * update gitignore * Minor fixes to AlephAlpha integration code * Tested npm i and rebuilt react * Force commit the react build * Update package version --------- Co-authored-by: Denise Wagenführ <denise.wagenfuehr@capgemini.com> Co-authored-by: fguderia <falko.guderian@capgemini.com> Co-authored-by: denise710 <53524926+denise710@users.noreply.github.com> Co-authored-by: wday-cs <119377799+wday-cs@users.noreply.github.com>
This commit is contained in:
parent
41bfef557a
commit
beeffd0ebb
183
.gitignore
vendored
183
.gitignore
vendored
@ -1,13 +1,180 @@
|
||||
*.DS_Store
|
||||
chainforge/react-server/node_modules
|
||||
__pycache__
|
||||
chainforge/cache
|
||||
chainforge/examples/oaievals/
|
||||
|
||||
# package build folders (sdist)
|
||||
chainforge.egg-info/
|
||||
dist/
|
||||
# == Below was generated by https://www.toptal.com/developers/gitignore/api/python ==
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=python
|
||||
|
||||
# venv
|
||||
venv
|
||||
node_modules
|
||||
### Python ###
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
### Python Patch ###
|
||||
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
|
||||
poetry.toml
|
||||
|
||||
# ruff
|
||||
.ruff_cache/
|
||||
|
||||
# LSP config files
|
||||
pyrightconfig.json
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/python
|
@ -36,6 +36,7 @@ Though you can run Chainforge, you can't do anything with it without the ability
|
||||
- HuggingFace models (via the HuggingFace Inference and Inference Endpoints API)
|
||||
- Anthropic models
|
||||
- Google PaLM2 chat and text bison models
|
||||
- Aleph Alpha Luminous Models
|
||||
- Azure OpenAI Endpoints
|
||||
- (Locally run) Alpaca and Llama models [Dalai](https://github.com/cocktailpeanut/dalai)-served Alpaca.7b at port 4000.
|
||||
- To query models like Alpaca and Llama run on your local machine via Dalai, [install `dalai`](https://github.com/cocktailpeanut/dalai) and follow the instructions to download `alpaca.7b`. When everything is setup, run `npx dalai serve 4000`.
|
||||
@ -48,6 +49,7 @@ To use a specific model provider, you need to do two things:
|
||||
- HuggingFace: `HUGGINGFACE_API_KEY`
|
||||
- Anthropic: `ANTHROPIC_API_KEY`
|
||||
- Google PaLM2: `PALM_API_KEY`
|
||||
- Aleph Alpha: `ALEPH_ALPHA_API_KEY`
|
||||
- Azure OpenAI: Set two keys, `AZURE_OPENAI_KEY` and `AZURE_OPENAI_ENDPOINT`. Note that the endpoint should look like a base URL. For examples on what these keys look like, see the [Azure OpenAI documentation](https://learn.microsoft.com/en-us/azure/cognitive-services/openai/chatgpt-quickstart?tabs=command-line&pivots=programming-language-javascript).
|
||||
- When you are done setting the API key(s), **reopen your terminal**. _(This is because the terminal loads the environment variables when it is first opened, so it needs to be refreshed before running `chainforge serve`.)_
|
||||
|
||||
|
1
chainforge/.python-version
Normal file
1
chainforge/.python-version
Normal file
@ -0,0 +1 @@
|
||||
3.10.6/envs/chainforge
|
@ -446,7 +446,8 @@ def fetchEnvironAPIKeys():
|
||||
'PALM_API_KEY': 'Google',
|
||||
'HUGGINGFACE_API_KEY': 'HuggingFace',
|
||||
'AZURE_OPENAI_KEY': 'Azure_OpenAI',
|
||||
'AZURE_OPENAI_ENDPOINT': 'Azure_OpenAI_Endpoint'
|
||||
'AZURE_OPENAI_ENDPOINT': 'Azure_OpenAI_Endpoint',
|
||||
'ALEPH_ALPHA_API_KEY': 'AlephAlpha'
|
||||
}
|
||||
d = { alias: os.environ.get(key) for key, alias in keymap.items() }
|
||||
ret = jsonify(d)
|
||||
|
157
chainforge/react-server/.gitignore
vendored
Normal file
157
chainforge/react-server/.gitignore
vendored
Normal file
@ -0,0 +1,157 @@
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/node,react
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=node,react
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
### Node Patch ###
|
||||
# Serverless Webpack directories
|
||||
.webpack/
|
||||
|
||||
# Optional stylelint cache
|
||||
|
||||
# SvelteKit build / generate output
|
||||
.svelte-kit
|
||||
|
||||
### react ###
|
||||
.DS_*
|
||||
**/*.backup.*
|
||||
**/*.back.*
|
||||
|
||||
node_modules
|
||||
|
||||
*.sublime*
|
||||
|
||||
psd
|
||||
thumb
|
||||
sketch
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/node,react
|
1
chainforge/react-server/.nvmrc
Normal file
1
chainforge/react-server/.nvmrc
Normal file
@ -0,0 +1 @@
|
||||
20.5.1
|
@ -1,15 +1,15 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.37690c8a.css",
|
||||
"main.js": "/static/js/main.4fb95aa3.js",
|
||||
"main.css": "/static/css/main.7d8c3568.css",
|
||||
"main.js": "/static/js/main.8233b961.js",
|
||||
"static/js/787.4c72bb55.chunk.js": "/static/js/787.4c72bb55.chunk.js",
|
||||
"index.html": "/index.html",
|
||||
"main.37690c8a.css.map": "/static/css/main.37690c8a.css.map",
|
||||
"main.4fb95aa3.js.map": "/static/js/main.4fb95aa3.js.map",
|
||||
"main.7d8c3568.css.map": "/static/css/main.7d8c3568.css.map",
|
||||
"main.8233b961.js.map": "/static/js/main.8233b961.js.map",
|
||||
"787.4c72bb55.chunk.js.map": "/static/js/787.4c72bb55.chunk.js.map"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.37690c8a.css",
|
||||
"static/js/main.4fb95aa3.js"
|
||||
"static/css/main.7d8c3568.css",
|
||||
"static/js/main.8233b961.js"
|
||||
]
|
||||
}
|
@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><script async src="https://www.googletagmanager.com/gtag/js?id=G-RN3FDBLMCR"></script><script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-RN3FDBLMCR")</script><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="A visual programming environment for prompt engineering"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>ChainForge</title><script defer="defer" src="/static/js/main.4fb95aa3.js"></script><link href="/static/css/main.37690c8a.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><script async src="https://www.googletagmanager.com/gtag/js?id=G-RN3FDBLMCR"></script><script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-RN3FDBLMCR")</script><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="A visual programming environment for prompt engineering"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>ChainForge</title><script defer="defer" src="/static/js/main.8233b961.js"></script><link href="/static/css/main.7d8c3568.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
chainforge/react-server/build/static/js/main.8233b961.js
Normal file
3
chainforge/react-server/build/static/js/main.8233b961.js
Normal file
File diff suppressed because one or more lines are too long
@ -115,6 +115,15 @@ License: MIT
|
||||
|
||||
/*! sheetjs (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Lodash <https://lodash.com/>
|
||||
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
||||
* Released under MIT license <https://lodash.com/license>
|
||||
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
||||
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react-dom.production.min.js
|
File diff suppressed because one or more lines are too long
9881
chainforge/react-server/package-lock.json
generated
9881
chainforge/react-server/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,9 @@
|
||||
"name": "chain-forge",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": "^20"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.4.4",
|
||||
"@azure/openai": "^1.0.0-beta.2",
|
||||
@ -15,6 +18,7 @@
|
||||
"@mantine/dropzone": "^6.0.19",
|
||||
"@mantine/form": "^6.0.11",
|
||||
"@mantine/prism": "^6.0.15",
|
||||
"reactflow": "^11.0",
|
||||
"@reactflow/background": "^11.2.0",
|
||||
"@reactflow/controls": "^11.1.11",
|
||||
"@reactflow/core": "^11.7.0",
|
||||
@ -74,7 +78,6 @@
|
||||
"react-device-detect": "^2.2.3",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-edit-text": "^5.1.0",
|
||||
"react-flow-renderer": "^10.3.17",
|
||||
"react-plotly.js": "^2.6.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"request": "^2.88.2",
|
||||
|
21
chainforge/react-server/src/App.js
vendored
21
chainforge/react-server/src/App.js
vendored
@ -5,10 +5,11 @@ import React, { useState, useCallback, useRef, useEffect } from 'react';
|
||||
import ReactFlow, {
|
||||
Controls,
|
||||
Background,
|
||||
} from 'react-flow-renderer';
|
||||
import { Button, Menu, LoadingOverlay, Text, Box, List, Loader, Header, Chip, Badge, Card, Accordion, Tooltip } from '@mantine/core';
|
||||
} from 'reactflow';
|
||||
import { Button, Menu, LoadingOverlay, Text, Box, List, Loader, Tooltip } from '@mantine/core';
|
||||
import { useClipboard } from '@mantine/hooks';
|
||||
import { IconSettings, IconTextPlus, IconTerminal, IconCsv, IconSettingsAutomation, IconFileSymlink, IconRobot, IconRuler2 } from '@tabler/icons-react';
|
||||
import RemoveEdge from './RemoveEdge';
|
||||
import TextFieldsNode from './TextFieldsNode'; // Import a custom node
|
||||
import PromptNode from './PromptNode';
|
||||
import EvaluatorNode from './EvaluatorNode';
|
||||
@ -23,11 +24,14 @@ import GlobalSettingsModal from './GlobalSettingsModal';
|
||||
import ExampleFlowsModal from './ExampleFlowsModal';
|
||||
import AreYouSureModal from './AreYouSureModal';
|
||||
import LLMEvaluatorNode from './LLMEvalNode';
|
||||
import { getDefaultModelFormData, getDefaultModelSettings, setCustomProviders } from './ModelSettingSchemas';
|
||||
import { getDefaultModelFormData, getDefaultModelSettings } from './ModelSettingSchemas';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import LZString from 'lz-string';
|
||||
import { EXAMPLEFLOW_1 } from './example_flows';
|
||||
import './text-fields-node.css';
|
||||
|
||||
// Styling
|
||||
import 'reactflow/dist/style.css'; // reactflow
|
||||
import './text-fields-node.css'; // project
|
||||
|
||||
// State management (from https://reactflow.dev/docs/guides/state-management/)
|
||||
import { shallow } from 'zustand/shallow';
|
||||
@ -70,8 +74,6 @@ const INITIAL_LLM = () => {
|
||||
return falcon7b;
|
||||
};
|
||||
|
||||
// import AnimatedConnectionLine from './AnimatedConnectionLine';
|
||||
|
||||
const nodeTypes = {
|
||||
textfields: TextFieldsNode, // Register the custom node
|
||||
prompt: PromptNode,
|
||||
@ -87,6 +89,10 @@ const nodeTypes = {
|
||||
comment: CommentNode,
|
||||
};
|
||||
|
||||
const edgeTypes = {
|
||||
default: RemoveEdge,
|
||||
};
|
||||
|
||||
// Whether we are running on localhost or not, and hence whether
|
||||
// we have access to the Flask backend for, e.g., Python code evaluation.
|
||||
const IS_RUNNING_LOCALLY = APP_IS_RUNNING_LOCALLY();
|
||||
@ -287,7 +293,7 @@ const App = () => {
|
||||
const uid = (id) => `${id}-${Date.now()}`;
|
||||
const starting_nodes = [
|
||||
{ id: uid('prompt'), type: 'prompt', data: {
|
||||
prompt: 'Why is the sky blue?',
|
||||
prompt: '',
|
||||
n: 1,
|
||||
llms: [INITIAL_LLM()] },
|
||||
position: { x: 450, y: 200 } },
|
||||
@ -694,6 +700,7 @@ const App = () => {
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
nodeTypes={nodeTypes}
|
||||
edgeTypes={edgeTypes}
|
||||
zoomOnPinch={false}
|
||||
zoomOnScroll={false}
|
||||
panOnScroll={true}
|
||||
|
2
chainforge/react-server/src/CsvNode.js
vendored
2
chainforge/react-server/src/CsvNode.js
vendored
@ -3,7 +3,7 @@ import { Text } from '@mantine/core';
|
||||
import useStore from './store';
|
||||
import NodeLabel from './NodeLabelComponent'
|
||||
import { IconCsv } from '@tabler/icons-react';
|
||||
import { Handle } from 'react-flow-renderer';
|
||||
import { Handle } from 'reactflow';
|
||||
|
||||
const CsvNode = ({ data, id }) => {
|
||||
const setDataPropsForNode = useStore((state) => state.setDataPropsForNode);
|
||||
|
2
chainforge/react-server/src/EvaluatorNode.js
vendored
2
chainforge/react-server/src/EvaluatorNode.js
vendored
@ -1,5 +1,5 @@
|
||||
import React, { useState, useRef, useCallback, useEffect } from 'react';
|
||||
import { Handle } from 'react-flow-renderer';
|
||||
import { Handle } from 'reactflow';
|
||||
import { Button, Code, Modal, Tooltip, Box, Text } from '@mantine/core';
|
||||
import { Prism } from '@mantine/prism';
|
||||
import { useDisclosure } from '@mantine/hooks';
|
||||
|
@ -164,6 +164,7 @@ const GlobalSettingsModal = forwardRef((props, ref) => {
|
||||
Azure_OpenAI: '',
|
||||
Azure_OpenAI_Endpoint: '',
|
||||
HuggingFace: '',
|
||||
AlephAlpha: '',
|
||||
},
|
||||
|
||||
validate: {
|
||||
@ -209,8 +210,7 @@ return (
|
||||
placeholder="Paste your OpenAI API key here"
|
||||
{...form.getInputProps('OpenAI')}
|
||||
/>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<TextInput
|
||||
label="HuggingFace API Key"
|
||||
placeholder="Paste your HuggingFace API key here"
|
||||
@ -231,7 +231,12 @@ return (
|
||||
{...form.getInputProps('Google')}
|
||||
/>
|
||||
<br />
|
||||
|
||||
<TextInput
|
||||
label="Aleph Alpha API Key"
|
||||
placeholder="Paste your Aleph Alpha API key here"
|
||||
{...form.getInputProps('AlephAlpha')}
|
||||
/>
|
||||
<br />
|
||||
<Divider my="xs" label="Microsoft Azure" labelPosition="center" />
|
||||
<TextInput
|
||||
label="Azure OpenAI Key"
|
||||
|
2
chainforge/react-server/src/InspectorNode.js
vendored
2
chainforge/react-server/src/InspectorNode.js
vendored
@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Handle } from 'react-flow-renderer';
|
||||
import { Handle } from 'reactflow';
|
||||
import useStore from './store';
|
||||
import NodeLabel from './NodeLabelComponent';
|
||||
import LLMResponseInspector, { exportToExcel } from './LLMResponseInspector';
|
||||
|
2
chainforge/react-server/src/LLMEvalNode.js
vendored
2
chainforge/react-server/src/LLMEvalNode.js
vendored
@ -1,5 +1,5 @@
|
||||
import React, { useState, useCallback, useRef, useEffect } from 'react';
|
||||
import { Handle } from 'react-flow-renderer';
|
||||
import { Handle } from 'reactflow';
|
||||
import { Alert, Progress, Textarea } from '@mantine/core';
|
||||
import { IconAlertTriangle, IconRobot, IconSearch } from "@tabler/icons-react";
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
851
chainforge/react-server/src/ModelSettingSchemas.js
vendored
851
chainforge/react-server/src/ModelSettingSchemas.js
vendored
File diff suppressed because it is too large
Load Diff
2
chainforge/react-server/src/PromptNode.js
vendored
2
chainforge/react-server/src/PromptNode.js
vendored
@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useState, useRef, useCallback, useMemo } from 'react';
|
||||
import { Handle } from 'react-flow-renderer';
|
||||
import { Handle } from 'reactflow';
|
||||
import { Switch, Progress, Textarea, Text, Popover, Center, Modal, Box, Tooltip } from '@mantine/core';
|
||||
import { useDisclosure } from '@mantine/hooks';
|
||||
import { IconList } from '@tabler/icons-react';
|
||||
|
68
chainforge/react-server/src/RemoveEdge.js
vendored
Normal file
68
chainforge/react-server/src/RemoveEdge.js
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
import React, { useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { BaseEdge, EdgeLabelRenderer, getBezierPath } from '@reactflow/core';
|
||||
import useStore from './store';
|
||||
|
||||
const EdgePathContainer = styled.g`
|
||||
path:nth-child(2) {
|
||||
pointer-events: all;
|
||||
&:hover {
|
||||
& + .edgebutton {
|
||||
// Make add node button visible
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
export default function CustomEdge({
|
||||
id,
|
||||
sourceX,
|
||||
sourceY,
|
||||
targetX,
|
||||
targetY,
|
||||
sourcePosition,
|
||||
targetPosition,
|
||||
style = {},
|
||||
markerEnd,
|
||||
}) {
|
||||
|
||||
const [edgePath, labelX, labelY] = getBezierPath({
|
||||
sourceX,
|
||||
sourceY,
|
||||
sourcePosition,
|
||||
targetX,
|
||||
targetY,
|
||||
targetPosition,
|
||||
});
|
||||
|
||||
const [hovering, setHovering] = useState(false);
|
||||
const removeEdge = useStore((state) => state.removeEdge);
|
||||
|
||||
const onEdgeClick = (evt, id) => {
|
||||
evt.stopPropagation();
|
||||
removeEdge(id);
|
||||
};
|
||||
|
||||
// Thanks in part to oshanley https://github.com/wbkd/react-flow/issues/1211#issuecomment-1585032930
|
||||
return (
|
||||
<EdgePathContainer onPointerEnter={()=>setHovering(true)} onPointerLeave={()=>setHovering(false)} onClick={()=>console.log('click')}>
|
||||
<BaseEdge path={edgePath} markerEnd={markerEnd} style={{...style, stroke: (hovering ? '#000' : '#999')}} />
|
||||
<EdgeLabelRenderer>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,
|
||||
fontSize: 12,
|
||||
pointerEvents: 'all',
|
||||
visibility: hovering ? 'inherit' : 'hidden',
|
||||
}}
|
||||
className="nodrag nopan"
|
||||
>
|
||||
<button className="remove-edge-btn" onClick={(event) => onEdgeClick(event, id)}>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
</EdgeLabelRenderer>
|
||||
</EdgePathContainer>
|
||||
);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { useState, useCallback, useEffect, useRef } from "react";
|
||||
import { Handle } from "react-flow-renderer";
|
||||
import { Handle } from "reactflow";
|
||||
import { NativeSelect, TextInput, Flex, Text, Box, Select, ActionIcon, Menu, Tooltip } from "@mantine/core";
|
||||
import { IconCaretDown, IconHash, IconRuler2, IconSearch, IconX } from "@tabler/icons-react";
|
||||
import NodeLabel from "./NodeLabelComponent";
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { Handle, useUpdateNodeInternals } from 'react-flow-renderer';
|
||||
import { Handle, useUpdateNodeInternals } from 'reactflow';
|
||||
import { Badge } from '@mantine/core';
|
||||
import useStore from './store'
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
||||
import { Handle } from 'react-flow-renderer';
|
||||
import { Handle } from 'reactflow';
|
||||
import { Textarea, Tooltip } from '@mantine/core';
|
||||
import { IconTextPlus, IconEye, IconEyeOff } from '@tabler/icons-react';
|
||||
import useStore from './store';
|
||||
|
2
chainforge/react-server/src/VisNode.js
vendored
2
chainforge/react-server/src/VisNode.js
vendored
@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { Handle } from 'react-flow-renderer';
|
||||
import { Handle } from 'reactflow';
|
||||
import { NativeSelect } from '@mantine/core';
|
||||
import useStore, { colorPalettes } from './store';
|
||||
import Plot from 'react-plotly.js';
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* @jest-environment jsdom
|
||||
*/
|
||||
import { call_anthropic, call_chatgpt, call_google_palm, extract_responses, merge_response_objs } from '../utils';
|
||||
import { call_alephalpha, call_anthropic, call_chatgpt, call_google_palm, extract_responses, merge_response_objs } from '../utils';
|
||||
import { LLM, NativeLLM } from '../models';
|
||||
import { expect, test } from '@jest/globals';
|
||||
import { LLMResponseObject } from '../typing';
|
||||
@ -106,3 +106,24 @@ test('google palm2 models', async () => {
|
||||
expect(typeof resps[0]).toBe('string');
|
||||
console.log(JSON.stringify(resps));
|
||||
}, 40000);
|
||||
|
||||
test('aleph alpha model', async () => {
|
||||
let [query, response] = await call_alephalpha("Who invented modern playing cards?", NativeLLM.Aleph_Alpha_Luminous_Base, 3, 0.7);
|
||||
expect(response).toHaveLength(3);
|
||||
|
||||
// Extract responses, check their type
|
||||
let resps = extract_responses(response, NativeLLM.Aleph_Alpha_Luminous_Base);
|
||||
expect(resps).toHaveLength(3);
|
||||
expect(typeof resps[0]).toBe('string');
|
||||
console.log(JSON.stringify(resps));
|
||||
|
||||
// Call Google's PaLM Text Completions API with a basic question
|
||||
[query, response] = await call_alephalpha("Who invented modern playing cards? The answer ", NativeLLM.Aleph_Alpha_Luminous_Base, 3, 0.7);
|
||||
expect(response).toHaveLength(3);
|
||||
|
||||
// Extract responses, check their type
|
||||
resps = extract_responses(response, NativeLLM.Aleph_Alpha_Luminous_Base);
|
||||
expect(resps).toHaveLength(3);
|
||||
expect(typeof resps[0]).toBe('string');
|
||||
console.log(JSON.stringify(resps));
|
||||
}, 40000);
|
||||
|
@ -548,6 +548,7 @@ export async function queryLLM(id: string,
|
||||
// Ensure llm param is an array
|
||||
if (typeof llm === 'string')
|
||||
llm = [ llm ];
|
||||
|
||||
llm = llm as (Array<string> | Array<Dict>);
|
||||
|
||||
await setAPIKeys(api_keys);
|
||||
@ -1162,4 +1163,4 @@ export async function loadCachedCustomProviders(): Promise<Dict> {
|
||||
}).then(function(res) {
|
||||
return res.json();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,14 @@ export enum NativeLLM {
|
||||
PaLM2_Text_Bison = "text-bison-001", // it's really models/text-bison-001, but that's confusing
|
||||
PaLM2_Chat_Bison = "chat-bison-001",
|
||||
|
||||
// Aleph Alpha
|
||||
Aleph_Alpha_Luminous_Extended = "luminous-extended",
|
||||
Aleph_Alpha_Luminous_ExtendedControl = "luminous-extended-control",
|
||||
Aleph_Alpha_Luminous_BaseControl = "luminous-base-control",
|
||||
Aleph_Alpha_Luminous_Base = "luminous-base",
|
||||
Aleph_Alpha_Luminous_Supreme = "luminous-supreme",
|
||||
Aleph_Alpha_Luminous_SupremeControl = "luminous-supreme-control",
|
||||
|
||||
// HuggingFace Inference hosted models, suggested to users
|
||||
HF_GPT2 = "gpt2",
|
||||
HF_BLOOM_560M = "bigscience/bloom-560m",
|
||||
@ -71,6 +79,7 @@ export enum LLMProvider {
|
||||
Anthropic = "anthropic",
|
||||
Google = "google",
|
||||
HuggingFace = "hf",
|
||||
Aleph_Alpha = "alephalpha",
|
||||
Custom = "__custom",
|
||||
}
|
||||
|
||||
@ -93,8 +102,11 @@ export function getProvider(llm: LLM): LLMProvider | undefined {
|
||||
return LLMProvider.HuggingFace;
|
||||
else if (llm.toString().startsWith('claude'))
|
||||
return LLMProvider.Anthropic;
|
||||
else if (llm_name?.startsWith('Aleph_Alpha'))
|
||||
return LLMProvider.Aleph_Alpha;
|
||||
else if (llm.toString().startsWith('__custom/'))
|
||||
return LLMProvider.Custom;
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,7 @@ let GOOGLE_PALM_API_KEY = get_environ("PALM_API_KEY");
|
||||
let AZURE_OPENAI_KEY = get_environ("AZURE_OPENAI_KEY");
|
||||
let AZURE_OPENAI_ENDPOINT = get_environ("AZURE_OPENAI_ENDPOINT");
|
||||
let HUGGINGFACE_API_KEY = get_environ("HUGGINGFACE_API_KEY");
|
||||
let ALEPH_ALPHA_API_KEY = get_environ("ALEPH_ALPHA_API_KEY");
|
||||
|
||||
/**
|
||||
* Sets the local API keys for the revelant LLM API(s).
|
||||
@ -117,6 +118,8 @@ export function set_api_keys(api_keys: StringDict): void {
|
||||
AZURE_OPENAI_KEY = api_keys['Azure_OpenAI'];
|
||||
if (key_is_present('Azure_OpenAI_Endpoint'))
|
||||
AZURE_OPENAI_ENDPOINT = api_keys['Azure_OpenAI_Endpoint'];
|
||||
if (key_is_present('AlephAlpha'))
|
||||
ALEPH_ALPHA_API_KEY = api_keys['AlephAlpha'];
|
||||
// Soft fail for non-present keys
|
||||
}
|
||||
|
||||
@ -621,6 +624,43 @@ export async function call_huggingface(prompt: string, model: LLM, n: number = 1
|
||||
return [query, responses];
|
||||
}
|
||||
|
||||
|
||||
export async function call_alephalpha(prompt: string, model: LLM, n: number = 1, temperature: number = 1.0, params?: Dict): Promise<[Dict, Dict]> {
|
||||
if (!ALEPH_ALPHA_API_KEY)
|
||||
throw Error("Could not find an API key for Aleph Alpha models. Double-check that your API key is set in Settings or in your local environment.");
|
||||
|
||||
const url: string = 'https://api.aleph-alpha.com/complete';
|
||||
let headers: StringDict = {'Content-Type': 'application/json', 'Accept': 'application/json'};
|
||||
if (ALEPH_ALPHA_API_KEY !== undefined)
|
||||
headers.Authorization = `Bearer ${ALEPH_ALPHA_API_KEY}`;
|
||||
|
||||
let data = JSON.stringify({
|
||||
"model": model.toString(),
|
||||
"prompt": prompt,
|
||||
"n": n,
|
||||
...params
|
||||
});
|
||||
|
||||
// Setup the args for the query
|
||||
let query: Dict = {
|
||||
model: model.toString(),
|
||||
n: n,
|
||||
temperature: temperature,
|
||||
...params, // 'the rest' of the settings, passed from the front-end settings
|
||||
};
|
||||
|
||||
const response = await fetch(url, {
|
||||
headers: headers,
|
||||
method: "POST",
|
||||
body: data,
|
||||
});
|
||||
const result = await response.json();
|
||||
const responses = await result.completions?.map((x: any) => x.completion);
|
||||
|
||||
return [query, responses];
|
||||
}
|
||||
|
||||
|
||||
async function call_custom_provider(prompt: string, model: LLM, n: number = 1, temperature: number = 1.0, params?: Dict): Promise<[Dict, Dict]> {
|
||||
if (!APP_IS_RUNNING_LOCALLY())
|
||||
throw new Error("The ChainForge app does not appear to be running locally. You can only call custom model providers if you are running ChainForge on your local machine, from a Flask app.")
|
||||
@ -651,7 +691,6 @@ async function call_custom_provider(prompt: string, model: LLM, n: number = 1, t
|
||||
|
||||
responses.push(response);
|
||||
}
|
||||
|
||||
return [query, responses];
|
||||
}
|
||||
|
||||
@ -662,7 +701,7 @@ export async function call_llm(llm: LLM, prompt: string, n: number, temperature:
|
||||
// Get the correct API call for the given LLM:
|
||||
let call_api: LLMAPICall | undefined;
|
||||
let llm_provider: LLMProvider = getProvider(llm);
|
||||
|
||||
|
||||
if (llm_provider === undefined)
|
||||
throw new Error(`Language model ${llm} is not supported.`);
|
||||
|
||||
@ -678,6 +717,8 @@ export async function call_llm(llm: LLM, prompt: string, n: number, temperature:
|
||||
call_api = call_anthropic;
|
||||
else if (llm_provider === LLMProvider.HuggingFace)
|
||||
call_api = call_huggingface;
|
||||
else if (llm_provider === LLMProvider.Aleph_Alpha)
|
||||
call_api = call_alephalpha;
|
||||
else if (llm_provider === LLMProvider.Custom)
|
||||
call_api = call_custom_provider;
|
||||
|
||||
@ -755,13 +796,19 @@ function _extract_huggingface_responses(response: Array<Dict>): Array<string>{
|
||||
return response.map((r: Dict) => r.generated_text.trim());
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the text part of a Aleph Alpha text completion.
|
||||
*/
|
||||
function _extract_alephalpha_responses(response: Dict): Array<string> {
|
||||
return response.map((r: string) => r.trim());
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a LLM and a response object from its API, extract the
|
||||
* text response(s) part of the response object.
|
||||
*/
|
||||
export function extract_responses(response: Array<string | Dict> | Dict, llm: LLM | string): Array<string> {
|
||||
let llm_provider: LLMProvider = getProvider(llm as LLM);
|
||||
|
||||
switch (llm_provider) {
|
||||
case LLMProvider.OpenAI:
|
||||
if (llm.toString().toLowerCase().includes('davinci'))
|
||||
@ -778,6 +825,8 @@ export function extract_responses(response: Array<string | Dict> | Dict, llm: LL
|
||||
return _extract_anthropic_responses(response as Dict[]);
|
||||
case LLMProvider.HuggingFace:
|
||||
return _extract_huggingface_responses(response as Dict[]);
|
||||
case LLMProvider.Aleph_Alpha:
|
||||
return _extract_alephalpha_responses(response);
|
||||
default:
|
||||
if (Array.isArray(response) && response.length > 0 && typeof response[0] === 'string')
|
||||
return response as string[];
|
||||
|
11
chainforge/react-server/src/store.js
vendored
11
chainforge/react-server/src/store.js
vendored
@ -3,7 +3,7 @@ import {
|
||||
addEdge,
|
||||
applyNodeChanges,
|
||||
applyEdgeChanges,
|
||||
} from 'react-flow-renderer';
|
||||
} from 'reactflow';
|
||||
import { escapeBraces } from './backend/template';
|
||||
import { filterDict } from './backend/utils';
|
||||
import { APP_IS_RUNNING_LOCALLY } from './backend/utils';
|
||||
@ -35,6 +35,7 @@ export let initLLMProviders = [
|
||||
{ name: "PaLM2", emoji: "🦬", model: "chat-bison-001", base_model: "palm2-bison", temp: 0.7 },
|
||||
{ name: "Azure OpenAI", emoji: "🔷", model: "azure-openai", base_model: "azure-openai", temp: 1.0 },
|
||||
{ name: "HuggingFace", emoji: "🤗", model: "tiiuae/falcon-7b-instruct", base_model: "hf", temp: 1.0 },
|
||||
{ name: "Aleph Alpha", emoji: "💡", model: "luminous-base", base_model: "luminous-base", temp: 0.0 }
|
||||
];
|
||||
if (APP_IS_RUNNING_LOCALLY()) {
|
||||
initLLMProviders.push({ name: "Dalai (Alpaca.7B)", emoji: "🦙", model: "alpaca.7B", base_model: "dalai", temp: 0.5 });
|
||||
@ -238,6 +239,11 @@ const useStore = create((set, get) => ({
|
||||
edges: newedges
|
||||
});
|
||||
},
|
||||
removeEdge: (id) => {
|
||||
set({
|
||||
edges: applyEdgeChanges([{id: id, type: 'remove'}], get().edges),
|
||||
});
|
||||
},
|
||||
onNodesChange: (changes) => {
|
||||
set({
|
||||
nodes: applyNodeChanges(changes, get().nodes),
|
||||
@ -262,8 +268,9 @@ const useStore = create((set, get) => ({
|
||||
get().setDataPropsForNode(target.id, { refresh: true });
|
||||
}
|
||||
|
||||
connection.interactionWidth = 100;
|
||||
connection.interactionWidth = 40;
|
||||
connection.markerEnd = {type: 'arrow', width: '22px', height: '22px'};
|
||||
connection.type = 'default';
|
||||
|
||||
set({
|
||||
edges: addEdge(connection, get().edges) // get().edges.concat(connection)
|
||||
|
@ -6,11 +6,6 @@
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
path.react-flow__edge-path:hover {
|
||||
stroke: #222;
|
||||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
background-color: #bbb;
|
||||
@ -122,7 +117,24 @@
|
||||
font-size: 10pt;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
|
||||
button.remove-edge-btn {
|
||||
border-radius: 50%;
|
||||
border-color: #ddd;
|
||||
border-style: solid;
|
||||
background-color: #ddd;
|
||||
cursor:pointer;
|
||||
}
|
||||
button.remove-edge-btn:hover {
|
||||
background-color: white;
|
||||
border-color: #fff;
|
||||
}
|
||||
button.remove-edge-btn:active {
|
||||
background-color: #777;
|
||||
color: #fff;
|
||||
border-color: #777;
|
||||
}
|
||||
|
||||
.input-field {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
Loading…
x
Reference in New Issue
Block a user