Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support optional query content #1097

Merged
merged 29 commits into from
Sep 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1724b87
feat: debug remove query content
iamjoel Jun 25, 2023
3535a7c
feat: support var type paragraph
iamjoel Jun 25, 2023
bff3bc1
chore: fiel
iamjoel Jun 25, 2023
cb86a80
feat: var render support paragraph
iamjoel Jun 25, 2023
60f6ab0
feat: webapp support paragraph
iamjoel Jun 25, 2023
8d6ec9a
feat: support clear
iamjoel Jun 26, 2023
a6db3e6
fix: clearbtn style
iamjoel Jun 26, 2023
32e0ddf
merge
iamjoel Aug 24, 2023
d16460a
fix: remove webapp query valid and i18n merge problem
iamjoel Aug 24, 2023
a4ee769
Merge branch 'main' into feat/generation-support-optional-query-content2
iamjoel Sep 4, 2023
e5f0de3
feat: completion model enable paragraph.
GarfieldDai Sep 5, 2023
16ecfe4
fix: var para type parse bug
iamjoel Sep 5, 2023
35ed3a1
fix: paragraph type
iamjoel Sep 5, 2023
71a9aee
feat: completion model enable paragraph.
GarfieldDai Sep 5, 2023
4fd364e
feat: update api doc
iamjoel Sep 5, 2023
a1ecb7f
feat: api doc
iamjoel Sep 5, 2023
8a08220
feat: batch run struct
iamjoel Sep 5, 2023
93959ea
feat: chat support paragraph var
iamjoel Sep 5, 2023
93b0287
chore: text generation api doc remove query
iamjoel Sep 6, 2023
79b78dd
feat: paragraph remove max length
iamjoel Sep 6, 2023
1b773ad
feat: prompt empty text generation can not be submitted
iamjoel Sep 6, 2023
6312769
chore: handle publish btn disabled
iamjoel Sep 6, 2023
db5a9ee
feat: completion model enable paragraph.
GarfieldDai Sep 6, 2023
f56d5ed
feat: completion model enable paragraph.
GarfieldDai Sep 6, 2023
ed56d12
fix: batch max length
iamjoel Sep 7, 2023
737bf61
feat: add data migration script.
GarfieldDai Sep 8, 2023
01d4059
add exception log.
GarfieldDai Sep 9, 2023
af507a3
bug fixed.
GarfieldDai Sep 9, 2023
0274c45
Merge branch 'main' into feat/generation-support-optional-query-content2
iamjoel Sep 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 106 additions & 3 deletions api/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import time

import click
from tqdm import tqdm
from flask import current_app
from langchain.embeddings import OpenAIEmbeddings
from werkzeug.exceptions import NotFound
Expand All @@ -21,9 +22,9 @@
from libs.helper import email as email_validate
from extensions.ext_database import db
from libs.rsa import generate_key_pair
from models.account import InvitationCode, Tenant
from models.account import InvitationCode, Tenant, TenantAccountJoin
from models.dataset import Dataset, DatasetQuery, Document
from models.model import Account
from models.model import Account, AppModelConfig, App
import secrets
import base64

Expand Down Expand Up @@ -439,6 +440,107 @@ def update_qdrant_indexes():

click.echo(click.style('Congratulations! Update {} dataset indexes.'.format(create_count), fg='green'))

@click.command('update_app_model_configs', help='Migrate data to support paragraph variable.')
@click.option("--batch-size", default=500, help="Number of records to migrate in each batch.")
def update_app_model_configs(batch_size):
pre_prompt_template = '{{default_input}}'
user_input_form_template = {
"en-US": [
{
"paragraph": {
"label": "Query",
"variable": "default_input",
"required": False,
"default": ""
}
}
],
"zh-Hans": [
{
"paragraph": {
"label": "查询内容",
"variable": "default_input",
"required": False,
"default": ""
}
}
]
}

click.secho("Start migrate old data that the text generator can support paragraph variable.", fg='green')

total_records = db.session.query(AppModelConfig) \
.join(App, App.app_model_config_id == AppModelConfig.id) \
.filter(App.mode == 'completion') \
.count()

if total_records == 0:
click.secho("No data to migrate.", fg='green')
return

num_batches = (total_records + batch_size - 1) // batch_size

with tqdm(total=total_records, desc="Migrating Data") as pbar:
for i in range(num_batches):
offset = i * batch_size
limit = min(batch_size, total_records - offset)

click.secho(f"Fetching batch {i+1}/{num_batches} from source database...", fg='green')

data_batch = db.session.query(AppModelConfig) \
.join(App, App.app_model_config_id == AppModelConfig.id) \
.filter(App.mode == 'completion') \
.order_by(App.created_at) \
.offset(offset).limit(limit).all()

if not data_batch:
click.secho("No more data to migrate.", fg='green')
break

try:
click.secho(f"Migrating {len(data_batch)} records...", fg='green')
for data in data_batch:
# click.secho(f"Migrating data {data.id}, pre_prompt: {data.pre_prompt}, user_input_form: {data.user_input_form}", fg='green')

if data.pre_prompt is None:
data.pre_prompt = pre_prompt_template
else:
if pre_prompt_template in data.pre_prompt:
continue
data.pre_prompt += pre_prompt_template

app_data = db.session.query(App) \
.filter(App.id == data.app_id) \
.one()

account_data = db.session.query(Account) \
.join(TenantAccountJoin, Account.id == TenantAccountJoin.account_id) \
.filter(TenantAccountJoin.role == 'owner') \
.filter(TenantAccountJoin.tenant_id == app_data.tenant_id) \
.one_or_none()

if not account_data:
continue

if data.user_input_form is None or data.user_input_form == 'null':
data.user_input_form = json.dumps(user_input_form_template[account_data.interface_language])
else:
raw_json_data = json.loads(data.user_input_form)
raw_json_data.append(user_input_form_template[account_data.interface_language][0])
data.user_input_form = json.dumps(raw_json_data)

# click.secho(f"Updated data {data.id}, pre_prompt: {data.pre_prompt}, user_input_form: {data.user_input_form}", fg='green')

db.session.commit()

except Exception as e:
click.secho(f"Error while migrating data: {e}, app_id: {data.app_id}, app_model_config_id: {data.id}", fg='red')
continue

click.secho(f"Successfully migrated batch {i+1}/{num_batches}.", fg='green')

pbar.update(len(data_batch))

def register_commands(app):
app.cli.add_command(reset_password)
app.cli.add_command(reset_email)
Expand All @@ -448,4 +550,5 @@ def register_commands(app):
app.cli.add_command(sync_anthropic_hosted_providers)
app.cli.add_command(clean_unused_dataset_indexes)
app.cli.add_command(create_qdrant_indexes)
app.cli.add_command(update_qdrant_indexes)
app.cli.add_command(update_qdrant_indexes)
app.cli.add_command(update_app_model_configs)
13 changes: 12 additions & 1 deletion api/constants/model_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,18 @@
"presence_penalty": 0,
"frequency_penalty": 0
}
})
}),
'user_input_form': json.dumps([
{
"paragraph": {
"label": "Query",
"variable": "query",
"required": True,
"default": ""
}
}
]),
'pre_prompt': '{{query}}'
}
},

Expand Down
2 changes: 1 addition & 1 deletion api/controllers/console/app/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def post(self, app_id):

parser = reqparse.RequestParser()
parser.add_argument('inputs', type=dict, required=True, location='json')
parser.add_argument('query', type=str, location='json')
parser.add_argument('query', type=str, location='json', default='')
parser.add_argument('model_config', type=dict, required=True, location='json')
parser.add_argument('response_mode', type=str, choices=['blocking', 'streaming'], location='json')
args = parser.parse_args()
Expand Down
2 changes: 1 addition & 1 deletion api/controllers/console/explore/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def post(self, installed_app):

parser = reqparse.RequestParser()
parser.add_argument('inputs', type=dict, required=True, location='json')
parser.add_argument('query', type=str, location='json')
parser.add_argument('query', type=str, location='json', default='')
parser.add_argument('response_mode', type=str, choices=['blocking', 'streaming'], location='json')
args = parser.parse_args()

Expand Down
2 changes: 1 addition & 1 deletion api/controllers/service_api/app/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def post(self, app_model, end_user):

parser = reqparse.RequestParser()
parser.add_argument('inputs', type=dict, required=True, location='json')
parser.add_argument('query', type=str, location='json')
parser.add_argument('query', type=str, location='json', default='')
parser.add_argument('response_mode', type=str, choices=['blocking', 'streaming'], location='json')
parser.add_argument('user', type=str, location='json')
args = parser.parse_args()
Expand Down
2 changes: 1 addition & 1 deletion api/controllers/web/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def post(self, app_model, end_user):

parser = reqparse.RequestParser()
parser.add_argument('inputs', type=dict, required=True, location='json')
parser.add_argument('query', type=str, location='json')
parser.add_argument('query', type=str, location='json', default='')
parser.add_argument('response_mode', type=str, choices=['blocking', 'streaming'], location='json')
args = parser.parse_args()

Expand Down
2 changes: 1 addition & 1 deletion api/core/model_providers/models/llm/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ def _get_prompt_and_stop(self, prompt_rules: dict, pre_prompt: str, inputs: dict
if order == 'context_prompt':
prompt += context_prompt_content
elif order == 'pre_prompt':
prompt += (pre_prompt_content + '\n\n') if pre_prompt_content else ''
prompt += pre_prompt_content

query_prompt = prompt_rules['query_prompt'] if 'query_prompt' in prompt_rules else '{{query}}'

Expand Down
2 changes: 1 addition & 1 deletion api/core/prompt/generate_prompts/baichuan_chat.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"pre_prompt",
"histories_prompt"
],
"query_prompt": "用户:{{query}}",
"query_prompt": "\n\n用户:{{query}}",
"stops": ["用户:"]
}
2 changes: 1 addition & 1 deletion api/core/prompt/generate_prompts/common_chat.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"pre_prompt",
"histories_prompt"
],
"query_prompt": "Human: {{query}}\n\nAssistant: ",
"query_prompt": "\n\nHuman: {{query}}\n\nAssistant: ",
"stops": ["\nHuman:", "</histories>"]
}
4 changes: 2 additions & 2 deletions api/services/app_model_config_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ def validate_configuration(tenant_id: str, account: Account, config: dict) -> di
variables = []
for item in config["user_input_form"]:
key = list(item.keys())[0]
if key not in ["text-input", "select"]:
raise ValueError("Keys in user_input_form list can only be 'text-input' or 'select'")
if key not in ["text-input", "select", "paragraph"]:
raise ValueError("Keys in user_input_form list can only be 'text-input', 'paragraph' or 'select'")

form_item = item[key]
if 'label' not in form_item:
Expand Down
6 changes: 3 additions & 3 deletions api/services/completion_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def completion(cls, app_model: App, user: Union[Account | EndUser], args: Any,
inputs = args['inputs']
query = args['query']

if not query:
if app_model.mode != 'completion' and not query:
raise ValueError('query is required')

query = query.replace('\x00', '')
Expand Down Expand Up @@ -347,8 +347,8 @@ def get_cleaned_inputs(cls, user_inputs: dict, app_model_config: AppModelConfig)
if value not in options:
raise ValueError(f"{variable} in input form must be one of the following: {options}")
else:
if 'max_length' in variable:
max_length = variable['max_length']
if 'max_length' in input_config:
max_length = input_config['max_length']
if len(value) > max_length:
raise ValueError(f'{variable} in input form must be less than {max_length} characters')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import type { FC } from 'react'
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import ModalFoot from '../modal-foot'
import type { Options } from '../config-select'
import ConfigSelect from '../config-select'
Expand All @@ -11,6 +12,7 @@ import s from './style.module.css'
import Toast from '@/app/components/base/toast'
import type { PromptVariable } from '@/models/debug'
import { getNewVar } from '@/utils/var'
import ConfigContext from '@/context/debug-configuration'

import Modal from '@/app/components/base/modal'

Expand All @@ -28,6 +30,7 @@ const ConfigModal: FC<IConfigModalProps> = ({
onClose,
onConfirm,
}) => {
const { modelConfig } = useContext(ConfigContext)
const { t } = useTranslation()
const { type, name, key, options, max_length } = payload || getNewVar('')

Expand All @@ -41,7 +44,7 @@ const ConfigModal: FC<IConfigModalProps> = ({
}
}

const isStringInput = tempType === 'string'
const isStringInput = tempType === 'string' || tempType === 'paragraph'
const title = isStringInput ? t('appDebug.variableConig.maxLength') : t('appDebug.variableConig.options')

// string type
Expand Down Expand Up @@ -93,22 +96,24 @@ const ConfigModal: FC<IConfigModalProps> = ({
<div className='mb-2'>
<div className={s.title}>{t('appDebug.variableConig.fieldType')}</div>
<div className='flex space-x-2'>
<SelectTypeItem type='string' selected={isStringInput} onClick={handleTypeChange('string')} />
<SelectTypeItem type='select' selected={!isStringInput} onClick={handleTypeChange('select')} />
<SelectTypeItem type='string' selected={tempType === 'string'} onClick={handleTypeChange('string')} />
<SelectTypeItem type='paragraph' selected={tempType === 'paragraph'} onClick={handleTypeChange('paragraph')} />
<SelectTypeItem type='select' selected={tempType === 'select'} onClick={handleTypeChange('select')} />
</div>
</div>

<div className='mt-6'>
<div className={s.title}>{title}</div>
{isStringInput
? (
<ConfigString value={tempMaxLength} onChange={setTempMaxValue} />
)
: (
<ConfigSelect options={tempOptions} onChange={setTempOptions} />
)}
</div>

{tempType !== 'paragraph' && (
<div className='mt-6'>
<div className={s.title}>{title}</div>
{isStringInput
? (
<ConfigString modelId={modelConfig.model_id} value={tempMaxLength} onChange={setTempMaxValue} />
)
: (
<ConfigSelect options={tempOptions} onChange={setTempOptions} />
)}
</div>
)}
</div>
<ModalFoot
onConfirm={handleConfirm}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import React, { useEffect } from 'react'

export type IConfigStringProps = {
value: number | undefined
modelId: string
onChange: (value: number | undefined) => void
}

Expand All @@ -13,6 +14,11 @@ const ConfigString: FC<IConfigStringProps> = ({
value,
onChange,
}) => {
useEffect(() => {
if (value && value > MAX_LENGTH)
onChange(MAX_LENGTH)
}, [value, MAX_LENGTH])

return (
<div>
<input
Expand All @@ -21,7 +27,13 @@ const ConfigString: FC<IConfigStringProps> = ({
min={1}
value={value || ''}
onChange={(e) => {
const value = Math.max(1, Math.min(MAX_LENGTH, parseInt(e.target.value))) || 1
let value = parseInt(e.target.value, 10)
if (value > MAX_LENGTH)
value = MAX_LENGTH

else if (value < 1)
value = 1

onChange(value)
}}
className="w-full px-3 text-sm leading-9 text-gray-900 border-0 rounded-lg grow h-9 bg-gray-50 focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200"
Expand Down
4 changes: 2 additions & 2 deletions web/app/components/app/configuration/config-var/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { Timeout } from 'ahooks/lib/useRequest/src/types'
import Panel from '../base/feature-panel'
import OperationBtn from '../base/operation-btn'
import VarIcon from '../base/icons/var-icon'
import EditModel from './config-model'
import EditModal from './config-modal'
import IconTypeIcon from './input-type-icon'
import type { IInputTypeIconProps } from './input-type-icon'
import s from './style.module.css'
Expand Down Expand Up @@ -240,7 +240,7 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
)}

{isShowEditModal && (
<EditModel
<EditModal
payload={currItem as PromptVariable}
isShow={isShowEditModal}
onClose={hideEditModal}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ const IconMap = (type: IInputTypeIconProps['type']) => {
<path fillRule="evenodd" clipRule="evenodd" d="M3.52593 0.166672H8.47411C8.94367 0.166665 9.33123 0.166659 9.64692 0.192452C9.97481 0.219242 10.2762 0.276738 10.5593 0.420991C10.9984 0.644695 11.3553 1.00165 11.579 1.44069C11.7233 1.72381 11.7808 2.02522 11.8076 2.35311C11.8334 2.6688 11.8334 3.05634 11.8334 3.5259V8.47411C11.8334 8.94367 11.8334 9.33121 11.8076 9.6469C11.7808 9.97479 11.7233 10.2762 11.579 10.5593C11.3553 10.9984 10.9984 11.3553 10.5593 11.579C10.2762 11.7233 9.97481 11.7808 9.64692 11.8076C9.33123 11.8334 8.94369 11.8333 8.47413 11.8333H3.52592C3.05636 11.8333 2.66882 11.8334 2.35312 11.8076C2.02523 11.7808 1.72382 11.7233 1.44071 11.579C1.00167 11.3553 0.644711 10.9984 0.421006 10.5593C0.276753 10.2762 0.219257 9.97479 0.192468 9.6469C0.166674 9.33121 0.16668 8.94366 0.166687 8.4741V3.52591C0.16668 3.05635 0.166674 2.6688 0.192468 2.35311C0.219257 2.02522 0.276753 1.72381 0.421006 1.44069C0.644711 1.00165 1.00167 0.644695 1.44071 0.420991C1.72382 0.276738 2.02523 0.219242 2.35312 0.192452C2.66882 0.166659 3.05637 0.166665 3.52593 0.166672ZM3.08335 3.08334C3.08335 2.76117 3.34452 2.50001 3.66669 2.50001H8.33335C8.65552 2.50001 8.91669 2.76117 8.91669 3.08334C8.91669 3.4055 8.65552 3.66667 8.33335 3.66667H6.58335V8.91667C6.58335 9.23884 6.32219 9.5 6.00002 9.5C5.67785 9.5 5.41669 9.23884 5.41669 8.91667V3.66667H3.66669C3.34452 3.66667 3.08335 3.4055 3.08335 3.08334Z" fill="#98A2B3" />
</svg>
),
paragraph: (
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M1.16669 5.83329C1.16669 5.51113 1.42785 5.24996 1.75002 5.24996H9.33335C9.65552 5.24996 9.91669 5.51113 9.91669 5.83329C9.91669 6.15546 9.65552 6.41663 9.33335 6.41663H1.75002C1.42785 6.41663 1.16669 6.15546 1.16669 5.83329Z" fill="#98A2B3"/>
<path fillRule="evenodd" clipRule="evenodd" d="M1.16669 3.49996C1.16669 3.17779 1.42785 2.91663 1.75002 2.91663H11.6667C11.9889 2.91663 12.25 3.17779 12.25 3.49996C12.25 3.82213 11.9889 4.08329 11.6667 4.08329H1.75002C1.42785 4.08329 1.16669 3.82213 1.16669 3.49996Z" fill="#98A2B3"/>
<path fillRule="evenodd" clipRule="evenodd" d="M1.16669 8.16663C1.16669 7.84446 1.42785 7.58329 1.75002 7.58329H11.6667C11.9889 7.58329 12.25 7.84446 12.25 8.16663C12.25 8.48879 11.9889 8.74996 11.6667 8.74996H1.75002C1.42785 8.74996 1.16669 8.48879 1.16669 8.16663Z" fill="#98A2B3"/>
<path fillRule="evenodd" clipRule="evenodd" d="M1.16669 10.5C1.16669 10.1778 1.42785 9.91663 1.75002 9.91663H9.33335C9.65552 9.91663 9.91669 10.1778 9.91669 10.5C9.91669 10.8221 9.65552 11.0833 9.33335 11.0833H1.75002C1.42785 11.0833 1.16669 10.8221 1.16669 10.5Z" fill="#98A2B3"/>
</svg>
),
select: (
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M7.48913 4.08334H3.01083C2.70334 4.08333 2.43804 4.08333 2.21955 4.10118C1.98893 4.12002 1.75955 4.16162 1.53883 4.27408C1.20955 4.44186 0.941831 4.70958 0.774053 5.03886C0.66159 5.25958 0.619989 5.48896 0.601147 5.71958C0.583295 5.93807 0.583304 6.20334 0.583313 6.51084V10.9892C0.583304 11.2967 0.583295 11.5619 0.601147 11.7804C0.619989 12.0111 0.66159 12.2404 0.774053 12.4612C0.941831 12.7904 1.20955 13.0582 1.53883 13.2259C1.75955 13.3384 1.98893 13.38 2.21955 13.3988C2.43803 13.4167 2.70329 13.4167 3.01077 13.4167H7.48912C7.7966 13.4167 8.06193 13.4167 8.28041 13.3988C8.51103 13.38 8.74041 13.3384 8.96113 13.2259C9.29041 13.0582 9.55813 12.7904 9.72591 12.4612C9.83837 12.2404 9.87997 12.0111 9.89882 11.7804C9.91667 11.5619 9.91666 11.2967 9.91665 10.9892V6.51087C9.91666 6.20336 9.91667 5.93808 9.89882 5.71958C9.87997 5.48896 9.83837 5.25958 9.72591 5.03886C9.55813 4.70958 9.29041 4.44186 8.96113 4.27408C8.74041 4.16162 8.51103 4.12002 8.28041 4.10118C8.06192 4.08333 7.79663 4.08333 7.48913 4.08334ZM7.70413 7.70416C7.93193 7.47635 7.93193 7.107 7.70413 6.8792C7.47632 6.65139 7.10697 6.65139 6.87917 6.8792L4.66665 9.09172L3.91246 8.33753C3.68465 8.10973 3.31531 8.10973 3.0875 8.33753C2.8597 8.56534 2.8597 8.93468 3.0875 9.16249L4.25417 10.3292C4.48197 10.557 4.85132 10.557 5.07913 10.3292L7.70413 7.70416Z" fill="#98A2B3" />
Expand Down
Loading