Skip to content

Commit

Permalink
Merge branch 'dev' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
louis-jan authored Apr 25, 2024
2 parents 3936ce1 + 957f462 commit 63a2f22
Show file tree
Hide file tree
Showing 21 changed files with 512 additions and 30 deletions.
7 changes: 2 additions & 5 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,13 @@ If applicable, add screenshots to help explain your issue.

**Environment details**
- Operating System: [Specify your OS. e.g., MacOS Sonoma 14.2.1, Windows 11, Ubuntu 22, etc]
- Jan Version: [e.g., 0.4.3]
- Jan Version: [e.g., 0.4.xxx nightly or manual]
- Processor: [e.g., Apple M1, Intel Core i7, AMD Ryzen 5, etc]
- RAM: [e.g., 8GB, 16GB]
- Any additional relevant hardware specifics: [e.g., Graphics card, SSD/HDD]

**Logs**
If the cause of the error is not clear, kindly provide your usage logs:
- `tail -n 50 ~/jan/logs/app.log` if you are using the UI
- `tail -n 50 ~/jan/logs/server.log` if you are using the local api server
Making sure to redact any private information.
If the cause of the error is not clear, kindly provide your usage logs: https://jan.ai/docs/troubleshooting#how-to-get-error-logs

**Additional context**
Add any other context or information that could be helpful in diagnosing the problem.
8 changes: 1 addition & 7 deletions .github/workflows/jan-electron-build-nightly.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
name: Jan Build Electron App Nightly or Manual
name: Electron Builder - Nightly / Manual

on:
push:
branches:
- main
paths-ignore:
- 'README.md'
- 'docs/**'
schedule:
- cron: '0 20 * * 1,2,3' # At 8 PM UTC on Monday, Tuesday, and Wednesday which is 3 AM UTC+7 Tuesday, Wednesday, and Thursday
workflow_dispatch:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/jan-electron-build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Jan Build Electron App
name: Electron Builder - Tag

on:
push:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/jan-electron-linter-and-test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Jan Electron Linter & Test
name: Test - Linter & Playwright
on:
workflow_dispatch:
push:
Expand Down
90 changes: 90 additions & 0 deletions .github/workflows/jan-openai-api-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Test - OpenAI API Pytest collection
on:
workflow_dispatch:
push:
branches:
- main
- dev
- release/**
paths:
- "docs/**"

pull_request:
branches:
- main
- dev
- release/**
paths:
- "docs/**"

jobs:
openai-python-tests:
runs-on: [self-hosted, Linux, ubuntu-desktop]
if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || github.event_name == 'push' || github.event_name == 'workflow_dispatch'
steps:
- name: Getting the repo
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Installing node
uses: actions/setup-node@v3
with:
node-version: 20

- name: "Cleanup cache"
continue-on-error: true
run: |
rm -rf ~/jan
make clean
- name: install dependencies
run: |
npm install -g @stoplight/prism-cli
- name: create python virtual environment and run test
run: |
python3 -m venv /tmp/jan
source /tmp/jan/bin/activate
# Clone openai-api-python repo
OPENAI_API_PYTHON_TAG=$(cat docs/openapi/version.txt)
git clone https://github.com/openai/openai-python.git
cd openai-python
git checkout $OPENAI_API_PYTHON_TAG
python3 -m venv /tmp/jan
source /tmp/jan/bin/activate
pip install -r requirements-dev.lock
pip install pytest-reportportal pytest-html
# Create pytest.ini file with content
cat ../docs/tests/pytest.ini >> pytest.ini
echo "rp_api_key = ${{ secrets.REPORT_PORTAL_API_KEY }}" >> pytest.ini
echo "rp_endpoint = ${{ secrets.REPORT_PORTAL_URL_PYTEST }}" >> pytest.ini
cat pytest.ini
# Append to conftest.py
cat ../docs/tests/conftest.py >> tests/conftest.py
# start mock server and run test then stop mock server
prism mock ../docs/openapi/jan.yaml > prism.log & prism_pid=$! && pytest --reportportal --html=report.html && kill $prism_pid
deactivate
- name: Upload Artifact
uses: actions/upload-artifact@v2
with:
name: report
path: |
openai-python/report.html
openai-python/assets
openai-python/prism.log
- name: clean up
if: always()
run: |
rm -rf /tmp/jan
rm -rf openai-python
rm -rf report.html
rm -rf report.zip

2 changes: 1 addition & 1 deletion .github/workflows/jan-server-build-nightly.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Jan Build Docker Nightly or Manual
name: Docker Builder - Nightly / Manual

on:
push:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/jan-server-build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Jan Build Docker
name: Docker Builder - Tag

on:
push:
Expand Down
20 changes: 18 additions & 2 deletions core/src/browser/extensions/engines/OAIEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ export abstract class OAIEngine extends AIEngine {
// The loaded model instance
loadedModel: Model | undefined

// Transform the payload
transformPayload?: Function

// Transform the response
transformResponse?: Function

/**
* On extension load, subscribe to events.
*/
Expand Down Expand Up @@ -78,13 +84,23 @@ export abstract class OAIEngine extends AIEngine {
}

const header = await this.headers()
let requestBody = {
messages: data.messages ?? [],
model: model.id,
stream: true,
...model.parameters,
}
if (this.transformPayload) {
requestBody = this.transformPayload(requestBody)
}

requestInference(
this.inferenceUrl,
data.messages ?? [],
requestBody,
model,
this.controller,
header
header,
this.transformResponse
).subscribe({
next: (content: any) => {
const messageContent: ThreadContent = {
Expand Down
23 changes: 11 additions & 12 deletions core/src/browser/extensions/engines/helpers/sse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,16 @@ import { ErrorCode, ModelRuntimeParams } from '../../../../types'
*/
export function requestInference(
inferenceUrl: string,
recentMessages: any[],
requestBody: any,
model: {
id: string
parameters: ModelRuntimeParams
},
controller?: AbortController,
headers?: HeadersInit
headers?: HeadersInit,
transformResponse?: Function
): Observable<string> {
return new Observable((subscriber) => {
const requestBody = JSON.stringify({
messages: recentMessages,
model: model.id,
stream: true,
...model.parameters,
})
fetch(inferenceUrl, {
method: 'POST',
headers: {
Expand All @@ -30,17 +25,17 @@ export function requestInference(
'Accept': model.parameters.stream ? 'text/event-stream' : 'application/json',
...headers,
},
body: requestBody,
body: JSON.stringify(requestBody),
signal: controller?.signal,
})
.then(async (response) => {
if (!response.ok) {
const data = await response.json()
let errorCode = ErrorCode.Unknown;
let errorCode = ErrorCode.Unknown
if (data.error) {
errorCode = data.error.code ?? data.error.type ?? ErrorCode.Unknown
} else if (response.status === 401) {
errorCode = ErrorCode.InvalidApiKey;
errorCode = ErrorCode.InvalidApiKey
}
const error = {
message: data.error?.message ?? 'Error occurred.',
Expand All @@ -52,7 +47,11 @@ export function requestInference(
}
if (model.parameters.stream === false) {
const data = await response.json()
subscriber.next(data.choices[0]?.message?.content ?? '')
if (transformResponse) {
subscriber.next(transformResponse(data))
} else {
subscriber.next(data.choices[0]?.message?.content ?? '')
}
} else {
const stream = response.body
const decoder = new TextDecoder('utf-8')
Expand Down
7 changes: 7 additions & 0 deletions core/src/types/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ChatCompletionMessage } from '../inference'

/**
* Native Route APIs
* @description Enum of all the routes exposed by the app
Expand Down Expand Up @@ -154,3 +156,8 @@ export const APIEvents = [
...Object.values(DownloadEvent),
...Object.values(LocalImportModelEvent),
]
export type PayloadType = {
messages: ChatCompletionMessage[]
model: string
stream: Boolean
}
1 change: 1 addition & 0 deletions docs/openapi/version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v1.23.2
6 changes: 6 additions & 0 deletions docs/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
def pytest_collection_modifyitems(items):
for item in items:
# add the name of the file (without extension) as a marker
filename = item.nodeid.split("::")[0].split("/")[-1].replace(".py", "")
marker = pytest.mark.file(filename)
item.add_marker(marker)
8 changes: 8 additions & 0 deletions docs/tests/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[pytest]
rp_project = openai-api-test
rp_launch = OpenAI Collection Test
rp_launch_description = Full collection to ensure compatibility with OpenAI API
rp_launch_attributes = 'CI'
filterwarnings = ignore::pytest.PytestUnknownMarkWarning
log_format = %(asctime)s %(levelname)s %(message)s
log_date_format = %Y-%m-%d %H:%M:%S
79 changes: 79 additions & 0 deletions extensions/inference-cohere-extension/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Cohere Engine Extension

Created using Jan extension example

# Create a Jan Extension using Typescript

Use this template to bootstrap the creation of a TypeScript Jan extension. 🚀

## Create Your Own Extension

To create your own extension, you can use this repository as a template! Just follow the below instructions:

1. Click the Use this template button at the top of the repository
2. Select Create a new repository
3. Select an owner and name for your new repository
4. Click Create repository
5. Clone your new repository

## Initial Setup

After you've cloned the repository to your local machine or codespace, you'll need to perform some initial setup steps before you can develop your extension.

> [!NOTE]
>
> You'll need to have a reasonably modern version of
> [Node.js](https://nodejs.org) handy. If you are using a version manager like
> [`nodenv`](https://github.com/nodenv/nodenv) or
> [`nvm`](https://github.com/nvm-sh/nvm), you can run `nodenv install` in the
> root of your repository to install the version specified in
> [`package.json`](./package.json). Otherwise, 20.x or later should work!
1. :hammer_and_wrench: Install the dependencies

```bash
npm install
```

1. :building_construction: Package the TypeScript for distribution

```bash
npm run bundle
```

1. :white_check_mark: Check your artifact

There will be a tgz file in your extension directory now

## Update the Extension Metadata

The [`package.json`](package.json) file defines metadata about your extension, such as
extension name, main entry, description and version.

When you copy this repository, update `package.json` with the name, description for your extension.

## Update the Extension Code

The [`src/`](./src/) directory is the heart of your extension! This contains the
source code that will be run when your extension functions are invoked. You can replace the
contents of this directory with your own code.

There are a few things to keep in mind when writing your extension code:

- Most Jan Extension functions are processed asynchronously.
In `index.ts`, you will see that the extension function will return a `Promise<any>`.

```typescript
import { events, MessageEvent, MessageRequest } from '@janhq/core'

function onStart(): Promise<any> {
return events.on(MessageEvent.OnMessageSent, (data: MessageRequest) =>
this.inference(data)
)
}
```

For more information about the Jan Extension Core module, see the
[documentation](https://github.com/janhq/jan/blob/main/core/README.md).

So, what are you waiting for? Go ahead and start customizing your extension!
Loading

0 comments on commit 63a2f22

Please sign in to comment.