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

refactor: service to model #132

Merged
merged 2 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
73 changes: 46 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,72 +1,91 @@
# ainize-js

A Typescript JS for the Ainize, a system for running AI services on the AI Network.
A Typescript JS for the Ainize, a system for running AI models on the AI Network.

## Requirements

node >= 16

## usage

### Install

```bash
npm install @ainize-team/ainize-js

yarn install @ainize-team/ainize-js
```

### Import
```typescript
import Ainize from '@ainize-team/ainize-js'
const ainize = new Ainize(<CHAIN_ID>);
```

CHAIN_ID

- 0: AI Network test net
- 1: AI Network main net

```typescript

import Ainize from '@ainize-team/ainize-js'
const ainize = new Ainize(<CHAIN_ID>);
```

### Login

You should login to ainize with AI Network account before deploy the container.

```typescript
ainize.login(<YOUR_PRIVATE_KEY>);
```

You can also login using [AIN Wallet](https://chromewebstore.google.com/detail/ain-wallet/hbdheoebpgogdkagfojahleegjfkhkpl) on the web.

```typescript
ainize.loginWithSigner();
```

This feature is supported from AIN Wallet version 2.0.5 or later.

### Deploy
You can deploy your AI service to ainize.
### Using model

You can use a model using `ainize.getModel(<MODEL_NAME>)`.

```typescript
const service = await ainize.deploy(<CONFIGURATION>);
const model = await ainize.getModel(<MODEL_NAME>);
```
CONFIGURATION
- serviceName: The name you want to deploying service.
- billingConfig: Billing configuration required for service usage.
- depositAddress: The address for receiving AIN deposits.
- costPerToken: Cost per token for service usage.
- minCost: Minimum cost.
- maxCost: Maximum cost. (optional)

You can stop or run your service container. Only service deployer can use this.
You should deposit AIN to AI model for credit before using model.

```typescript
service.stop();
service.run();
await model.chargeCredit(<AMOUNT>);
const balance = await model.getCreditBalance();
```

### Using Service
You can use a service using `ainize.getService(<SERVICE_NAME>)`.
If you have enough credit, you can use the model.

```typescript
const service = await ainize.getService(<SERVICE_NAME>);
const result = await model.request(<REQUEST_DATA>);
```

You should deposit AIN to credit before using service.
### Deploy

You can deploy your AI model to ainize. Anyone can use your AI model with AIN token.

CONFIGURATION(JSON)

- modelName: The name you want to deploying model.
- billingConfig: Billing configuration required for model usage.
- depositAddress: The address for receiving AIN deposits.
- costPerToken: Cost per token for model usage.
- minCost: Minimum cost.
- maxCost: Maximum cost. (optional)

```typescript
await service.chargeCredit(<AMOUNT>);
const balance = await service.getCreditBalance();
const model = await ainize.deploy(<CONFIGURATION>);
```

If you have enough credit, you can use the service.
You can stop or run your model container. Only model deployer can use this.

```typescript
const result = await service.request(<REQUEST_DATA>);
```
model.stop();
model.run();
```
46 changes: 23 additions & 23 deletions src/ainize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Middleware from "./middlewares/middleware";
import { DEFAULT_BILLING_CONFIG, Path } from "./constants";
import Handler from "./handlers/handler";
import AppController from "./controllers/appController";
import Service from "./service";
import Model from "./model";
import { deployConfig } from "./types/type";
import AinModule from "./ain";
import Internal from "./internal";
Expand Down Expand Up @@ -79,12 +79,12 @@ export default class Ainize {

// FIXME(yoojin): add config type and change param type.
/**
* Deploy AI service container.
* @param {deployConfig} deployConfig Set configuration for setting container. serviceName, billingConfig, etc.
* @returns {Service} Deployed service object.
* Deploy AI model container.
* @param {deployConfig} deployConfig Set configuration for setting container. modelName, billingConfig, etc.
* @returns {Model} Deployed model object.
*/
// TODO(yoojin, woojae): Deploy container, advanced.
async deploy({serviceName, billingConfig, serviceUrl}: deployConfig): Promise<Service> {
async deploy({modelName, billingConfig, modelUrl}: deployConfig): Promise<Model> {
// TODO(yoojin, woojae): Add container deploy logic.
const result = await new Promise(async (resolve, reject) => {
const deployer = await this.ain.getAddress();
Expand All @@ -94,31 +94,31 @@ export default class Ainize {
depositAddress: deployer,
};
}
// NOTE(yoojin): For test. We make fixed url on service.
if (!serviceUrl) {
serviceUrl = `https://${serviceName}.ainetwork.xyz`;
// NOTE(yoojin): For test. We make fixed url on model.
if (!modelUrl) {
modelUrl = `https://${modelName}.ainetwork.xyz`;
}
serviceUrl = serviceUrl.replace(/\/$/, '');
const servicePath = Path.app(serviceName).status();
await this.handler.subscribe(servicePath, resolve);
await this.appController.createApp({ appName: serviceName, serviceUrl, billingConfig });
modelUrl = modelUrl.replace(/\/$/, '');
const modelPath = Path.app(modelName).status();
await this.handler.subscribe(modelPath, resolve);
await this.appController.createApp({ appName: modelName, modelUrl, billingConfig });
});
console.log(`${serviceName} deploy success!`);
return this.getService(serviceName);
console.log(`${modelName} deploy success!`);
return this.getModel(modelName);
}

/**
* Get deployed service.
* @param serviceName
* @returns {Service} Deployed service object.
* Get deployed model.
* @param modelName
* @returns {Model} Deployed model object.
*/
async getService(serviceName: string): Promise<Service> {
const servicePath = Path.app(serviceName).root();
const serviceData = await this.ain.getValue(servicePath, { is_shallow: true });
if(!serviceData) {
throw new Error("Service not found");
async getModel(modelName: string): Promise<Model> {
const modelPath = Path.app(modelName).root();
const modelData = await this.ain.getValue(modelPath, { is_shallow: true });
if(!modelData) {
throw new Error("Model not found");
}
return new Service(serviceName);
return new Model(modelName);
}

test() {
Expand Down
8 changes: 4 additions & 4 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ export const Path = {
deposit: () => `${Path.app(appName).root()}/deposit`,
depositOfUser: (userAddress: string) => `${Path.app(appName).deposit()}/${userAddress}`,
billingConfig: () => `${Path.app(appName).root()}/billingConfig`,
service: () => `${Path.app(appName).root()}/service`,
userOfService: (userAddress: string) =>
`${Path.app(appName).service()}/${userAddress}`,
model: () => `${Path.app(appName).root()}/model`,
userOfModel: (userAddress: string) =>
`${Path.app(appName).model()}/${userAddress}`,
requestKey: (userAddress: string, requestKey: string) =>
`${Path.app(appName).userOfService(userAddress)}/${requestKey}`,
`${Path.app(appName).userOfModel(userAddress)}/${requestKey}`,
request: (userAddress: string, requestKey: string) =>
`${Path.app(appName).requestKey(userAddress, requestKey)}/request`,
response: (userAddress: string, requestKey: string) =>
Expand Down
22 changes: 11 additions & 11 deletions src/controllers/appController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default class AppController {
return AppController.instance;
}

async createApp({ appName, serviceUrl, billingConfig }: createAppConfig) {
async createApp({ appName, modelUrl, billingConfig }: createAppConfig) {
const setRuleOps: SetOperation[] = [];
const setFunctionOps: SetOperation[] = [];
const setBillingConfigOps: SetOperation[] = [] ;
Expand All @@ -29,7 +29,7 @@ export default class AppController {
}

const depositPath = `${Path.app(appName).depositOfUser("$userAddress")}/$transferKey`
const depositUrl = `${serviceUrl}/deposit`;
const depositUrl = `${modelUrl}/deposit`;
const depositParam: setTriggerFunctionParm = {
ref: depositPath,
function_id: "deposit-trigger",
Expand All @@ -40,17 +40,17 @@ export default class AppController {
const depositFuncOp = buildSetOperation("SET_FUNCTION", depositParam.ref, depositValue);
setFunctionOps.push(depositFuncOp);

const serviceFuncPath = Path.app(appName).request("$userAddress", "$requestKey")
const serviceFuncUrl = `${serviceUrl}/service`;
const serviceFuncParam: setTriggerFunctionParm = {
ref: serviceFuncPath,
function_id: "service-trigger",
const modelFuncPath = Path.app(appName).request("$userAddress", "$requestKey")
const modelFuncUrl = `${modelUrl}/model`;
const modelFuncParam: setTriggerFunctionParm = {
ref: modelFuncPath,
function_id: "model-trigger",
function_type: "REST",
function_url: serviceFuncUrl
function_url: modelFuncUrl
}
const serviceFuncValue = this.buildSetFunctionValue(serviceFuncParam);
const serviceFuncOp = buildSetOperation("SET_FUNCTION", serviceFuncParam.ref, serviceFuncValue);
setFunctionOps.push(serviceFuncOp);
const modelFuncValue = this.buildSetFunctionValue(modelFuncParam);
const modelFuncOp = buildSetOperation("SET_FUNCTION", modelFuncParam.ref, modelFuncValue);
setFunctionOps.push(modelFuncOp);

const configOp = this.buildSetAppBillingConfigOp(appName, billingConfig);
setBillingConfigOps.push(configOp);
Expand Down
Loading
Loading