Skip to content

Commit

Permalink
1.72.2 (#308)
Browse files Browse the repository at this point in the history
# PR Checklist
- [X] Did you check if it works normally in all models? *ignore this
when it dosen't uses models*
- [X] Did you check if it works normally in all of web, local and node
hosted versions? if it dosen't, did you blocked it in those versions?
- [X] Did you added a type def?

# Description
  • Loading branch information
kwaroran authored Mar 13, 2024
2 parents 9490c18 + a8a8347 commit 8c49165
Show file tree
Hide file tree
Showing 10 changed files with 215 additions and 35 deletions.
10 changes: 8 additions & 2 deletions android/app/src/main/java/co/aiclient/risu/MainActivity.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package co.aiclient.risu;

import android.os.Bundle;
import com.getcapacitor.BridgeActivity;

public class MainActivity extends BridgeActivity {}
public class MainActivity extends BridgeActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
registerPlugin(StreamedPlugin.class);
super.onCreate(savedInstanceState);
}
}
119 changes: 119 additions & 0 deletions android/app/src/main/java/co/aiclient/risu/StreamedPlugin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package co.aiclient.risu;

import android.util.Base64;

import com.getcapacitor.JSObject;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;

@CapacitorPlugin(name = "streamedFetch")
public class StreamedPlugin extends Plugin {



@PluginMethod()
public void streamedFetch(PluginCall call) {
String id = call.getString("id");
String urlParam = call.getString("url");
String bodyString = call.getString("body");
JSObject headers = call.getObject("headers");


URL url = null;

try {
url = new URL(urlParam);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
byte[] bodyEncodedByte = bodyString.getBytes("UTF-8");
byte[] bodyByte = Base64.decode(bodyEncodedByte, Base64.DEFAULT);
Iterator<String> keys = headers.keys();
urlConnection.setRequestMethod("POST");
while(keys.hasNext()) {
String key = keys.next();
if (headers.get(key) instanceof JSONObject) {
urlConnection.setRequestProperty(key, headers.getString(key));
}
}
urlConnection.setRequestProperty("Content-Length", String.valueOf(bodyByte.length));
urlConnection.setDoInput(true);
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
out.write(bodyByte);
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
int resCode = urlConnection.getResponseCode();
JSObject resObj = new JSObject();
JSObject headerObj = new JSObject();
resObj.put("id", id);
resObj.put("type", "headers");
resObj.put("status", resCode);

int i = 0;
while (true){
String headerName = urlConnection.getHeaderFieldKey(i);
String headerValue = urlConnection.getHeaderField(i);
i++;

if(headerValue == null){
break;
}
if(headerName == null){
continue;
}

headerObj.put(headerName, headerValue);
}
resObj.put("body", headerObj);
notifyListeners("streamed_fetch", resObj);

while (true){
int ableBytes = in.available();
byte[] buf = new byte[ableBytes];
int bytesRead = in.read(buf, 0, ableBytes);
if(bytesRead == -1){
break;
}
byte[] encodedBuf = Base64.encode(buf, Base64.DEFAULT);
JSObject obj = new JSObject();
obj.put("id", id);
obj.put("body", encodedBuf);
obj.put("type", "chunk");
notifyListeners("streamed_fetch", obj);
}
JSObject endObj = new JSObject();
endObj.put("id", id);
endObj.put("type", "end");
notifyListeners("streamed_fetch", endObj);
} finally {
urlConnection.disconnect();
}
} catch (IOException e) {
JSObject obj = new JSObject();
obj.put("error", String.valueOf(e));
call.resolve(obj);
return;
} catch (JSONException e) {
JSObject obj = new JSObject();
obj.put("error", String.valueOf(e));
call.resolve(obj);
return;
}

JSObject ret = new JSObject();
ret.put("success", true);
call.resolve(ret);
}
}
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.0.0'
classpath 'com.android.tools.build:gradle:8.1.3'
classpath 'com.google.gms:google-services:4.3.15'

// NOTE: Do not place your application dependencies here; they belong
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"package": {
"productName": "RisuAI",
"version": "1.82.1"
"version": "1.82.2"
},
"tauri": {
"allowlist": {
Expand Down
9 changes: 8 additions & 1 deletion src/lib/ChatScreens/Chat.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@
let msgDisplay = ''
let translated = get(DataBase).autoTranslate
async function rm(){
async function rm(e:MouseEvent){
if(e.shiftKey){
let msg = $CurrentChat.message
msg = msg.slice(0, idx)
$CurrentChat.message = msg
return
}
const rm = $DataBase.askRemoval ? await alertConfirm(language.removeChat) : true
if(rm){
if($DataBase.instantRemove){
Expand Down
5 changes: 4 additions & 1 deletion src/lib/UI/ModelList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@
return 'Mistral Small'
case 'mistral-medium-latest':
return 'Mistral Medium'
case 'claude-3-haiku-20240307':
return 'Claude 3 Haiku (20240307)'
default:
if(name.startsWith("horde:::")){
const split = name.split(":::")
Expand Down Expand Up @@ -157,7 +159,8 @@
</Arcodion>
<Arcodion name="Anthropic Claude">
<button class="p-2 hover:text-green-500" on:click={() => {changeModel('claude-3-opus-20240229')}}>Claude 3 Opus (20240229)</button>
<button class="p-2 hover:text-green-500" on:click={() => {changeModel('claude-3-sonnet-20240229')}}>Claude 3 sonnet (20240229)</button>
<button class="p-2 hover:text-green-500" on:click={() => {changeModel('claude-3-sonnet-20240229')}}>Claude 3 Sonnet (20240229)</button>
<button class="p-2 hover:text-green-500" on:click={() => {changeModel('claude-3-haiku-20240307')}}>Claude 3 Haiku (20240307)</button>
{#if showUnrec}
<button class="p-2 hover:text-green-500" on:click={() => {changeModel('claude-2.1')}}>claude-2.1</button>
<button class="p-2 hover:text-green-500" on:click={() => {changeModel('claude-2')}}>claude-2</button>
Expand Down
3 changes: 3 additions & 0 deletions src/ts/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,9 @@ const matcher = (p1:string,matcherArg:matcherArg) => {
}

const smMatcher = (p1:string,matcherArg:matcherArg) => {
if(!p1){
return null
}
const lowerCased = p1.toLocaleLowerCase()
const db = matcherArg.db
const chara = matcherArg.chara
Expand Down
2 changes: 1 addition & 1 deletion src/ts/storage/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type { OobaChatCompletionRequestParams } from '../model/ooba';

export const DataBase = writable({} as any as Database)
export const loadedStore = writable(false)
export let appVer = "1.82.1"
export let appVer = "1.82.2"
export let webAppSubVer = ''

export function setDatabase(data:Database){
Expand Down
96 changes: 69 additions & 27 deletions src/ts/storage/globalApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import * as CapFS from '@capacitor/filesystem'
import { save } from "@tauri-apps/api/dialog";
import type { RisuModule } from "../process/modules";
import { listen } from '@tauri-apps/api/event'
import { registerPlugin } from '@capacitor/core';

//@ts-ignore
export const isTauri = !!window.__TAURI__
Expand Down Expand Up @@ -1281,7 +1282,7 @@ export class LocalWriter{
}

let fetchIndex = 0
let tauriNativeFetchData:{[key:string]:StreamedFetchChunk[]} = {}
let nativeFetchData:{[key:string]:StreamedFetchChunk[]} = {}

interface StreamedFetchChunkData{
type:'chunk',
Expand All @@ -1302,16 +1303,39 @@ interface StreamedFetchEndData{
}

type StreamedFetchChunk = StreamedFetchChunkData|StreamedFetchHeaderData|StreamedFetchEndData
interface StreamedFetchPlugin {
streamedFetch(options: { id: string, url:string, body:string, headers:{[key:string]:string} }): Promise<{"error":string,"success":boolean}>;
addListener(eventName: 'streamed_fetch', listenerFunc: (data:StreamedFetchChunk) => void): void;
}

listen('streamed_fetch', (event) => {
try {
const parsed = JSON.parse(event.payload as string)
const id = parsed.id
tauriNativeFetchData[id]?.push(parsed)
} catch (error) {
console.error(error)
}
})
let streamedFetchListening = false
let capStreamedFetch:StreamedFetchPlugin|undefined

if(isTauri){
listen('streamed_fetch', (event) => {
try {
const parsed = JSON.parse(event.payload as string)
const id = parsed.id
nativeFetchData[id]?.push(parsed)
} catch (error) {
console.error(error)
}
}).then((v) => {
streamedFetchListening = true
})
}
if(Capacitor.isNativePlatform()){
capStreamedFetch = registerPlugin<StreamedFetchPlugin>('CapacitorHttp', CapacitorHttp)

capStreamedFetch.addListener('streamed_fetch', (data) => {
try {
nativeFetchData[data.id]?.push(data)
} catch (error) {
console.error(error)
}
})
streamedFetchListening = true
}

export async function fetchNative(url:string, arg:{
body:string,
Expand All @@ -1323,7 +1347,7 @@ export async function fetchNative(url:string, arg:{
let headers = arg.headers ?? {}
const db = get(DataBase)
let throughProxi = (!isTauri) && (!isNodeServer) && (!db.usePlainFetch) && (!Capacitor.isNativePlatform())
if(isTauri){
if(isTauri || Capacitor.isNativePlatform()){
fetchIndex++
if(arg.signal && arg.signal.aborted){
throw new Error('aborted')
Expand All @@ -1332,31 +1356,49 @@ export async function fetchNative(url:string, arg:{
fetchIndex = 0
}
let fetchId = fetchIndex.toString().padStart(5,'0')
tauriNativeFetchData[fetchId] = []
nativeFetchData[fetchId] = []
let resolved = false

let error = ''
invoke('streamed_fetch', {
id: fetchId,
url: url,
headers: JSON.stringify(headers),
body: arg.body,
}).then((res) => {
const parsedRes = JSON.parse(res as string)
if(!parsedRes.success){
error = parsedRes.body
resolved = true
}
})
while(!streamedFetchListening){
await sleep(100)
}
if(isTauri){
invoke('streamed_fetch', {
id: fetchId,
url: url,
headers: JSON.stringify(headers),
body: arg.body,
}).then((res) => {
const parsedRes = JSON.parse(res as string)
if(!parsedRes.success){
error = parsedRes.body
resolved = true
}
})
}
else if(capStreamedFetch){
capStreamedFetch.streamedFetch({
id: fetchId,
url: url,
headers: headers,
body: Buffer.from(arg.body).toString('base64'),
}).then((res) => {
if(!res.success){
error = res.error
resolved = true
}
})
}

let resHeaders:{[key:string]:string} = null
let status = 400

const readableStream = new ReadableStream<Uint8Array>({
async start(controller) {
while(!resolved || tauriNativeFetchData[fetchId].length > 0){
if(tauriNativeFetchData[fetchId].length > 0){
const data = tauriNativeFetchData[fetchId].shift()
while(!resolved || nativeFetchData[fetchId].length > 0){
if(nativeFetchData[fetchId].length > 0){
const data = nativeFetchData[fetchId].shift()
console.log(data)
if(data.type === 'chunk'){
const chunk = Buffer.from(data.body, 'base64')
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":"1.82.1"}
{"version":"1.82.2"}

0 comments on commit 8c49165

Please sign in to comment.