Skip to content

Commit

Permalink
Merge pull request ubiquity-os-marketplace#181 from gentlementlegen/f…
Browse files Browse the repository at this point in the history
…eat/webpage

feat/webpage
  • Loading branch information
gentlementlegen authored Nov 19, 2024
2 parents 365ff53 + b3a3a94 commit a5875e9
Show file tree
Hide file tree
Showing 27 changed files with 728 additions and 83 deletions.
7 changes: 5 additions & 2 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"tests/**",
"dist/**",
"eslint.config.mjs",
"output.html"
"output.html",
"src/web/api/payload.ts"
],
"useGitignore": true,
"language": "en",
Expand All @@ -27,7 +28,9 @@
"knip",
"hellip",
"mswjs",
"Rpcs"
"Rpcs",
"sonarjs",
"pico"
],
"dictionaries": ["typescript", "node", "software-terms"],
"import": [
Expand Down
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ SUPABASE_URL=""
SUPABASE_KEY=""

# X25519 private key
X25519_PRIVATE_KEY=""
X25519_PRIVATE_KEY="wrQ9wTI1bwdAHbxk2dfsvoK1yRwDc0CEenmMXFvGYgY"

# Only used for local run, matches X25519_PRIVATE_KEY example key
EVM_PRIVATE_ENCRYPTED="kmpTKq5Wh9r9x5j3U9GqZr3NYnjK2g0HtbzeUBOuLC2y3x8ja_SKBNlB2AZ6LigXHP_HeMitftVUtzmoj8CFfVP9SqjWoL6IPku1hVTWkdTn97g1IxzmjydFxjdcf0wuDW1hvVtoq3Uw5yALABqxcQ"

# NFT minter private key
NFT_MINTER_PRIVATE_KEY=""
Expand Down
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# `@ubiquity-os/text-conversation-rewards`

## How to Get Started

1. **Install dependencies**: Make sure you have [Bun](https://bun.sh/) installed, then run:

```sh
bun install
```

2. **Build the UI for production**:

```sh
cd src/web && bun run ui:build
```

3. **Copy and paste the `.env.example` and populate the environment variables**

4. **Start the server**:

```sh
bun run server
```

## Data structure

```json
Expand Down Expand Up @@ -52,7 +74,6 @@ Here is a possible valid configuration to enable this plugin. See [these files](
```yaml
plugin: ubiquity-os/conversation-rewards
with:
logLevel: "info"
evmNetworkId: 100
evmPrivateEncrypted: "encrypted-key"
erc20RewardToken: "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d"
Expand Down
Binary file modified bun.lockb
Binary file not shown.
8 changes: 4 additions & 4 deletions dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion knip.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { KnipConfig } from "knip";

const config: KnipConfig = {
entry: ["src/index.ts"],
entry: ["src/index.ts", "src/web/api/index.ts"],
project: ["src/**/*.ts"],
ignore: ["src/data-collection/examples/*.ts", "src/configuration/common-config-type.ts", "dist/**"],
ignoreExportsUsedInFile: true,
Expand Down
25 changes: 0 additions & 25 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,6 @@
"default": {},
"type": "object",
"properties": {
"logLevel": {
"default": "info",
"anyOf": [
{
"const": "fatal",
"type": "string"
},
{
"const": "error",
"type": "string"
},
{
"const": "info",
"type": "string"
},
{
"const": "verbose",
"type": "string"
},
{
"const": "debug",
"type": "string"
}
]
},
"evmNetworkId": {
"default": 100,
"type": "number"
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"format:cspell": "cspell **/*",
"knip": "knip",
"prepare": "husky install",
"dev": "bun --watch src/index.ts"
"dev": "bun --watch src/index.ts",
"server": "bun --watch src/web/api/index.ts"
},
"keywords": [
"typescript",
Expand Down Expand Up @@ -45,7 +46,7 @@
"openai": "4.56.0",
"ts-jest": "^29.2.5",
"tsx": "4.7.1",
"yaml": "2.4.1"
"yaml": "^2.6.0"
},
"devDependencies": {
"@babel/core": "7.23.9",
Expand All @@ -69,6 +70,7 @@
"eslint": "9.12.0",
"eslint-plugin-check-file": "^2.8.0",
"eslint-plugin-sonarjs": "2.0.3",
"hono": "^4.6.10",
"husky": "8.0.3",
"jest": "29.7.0",
"jest-junit": "16.0.0",
Expand All @@ -78,6 +80,8 @@
"msw": "2.4.9",
"npm-run-all": "4.1.5",
"prettier": "3.3.3",
"sqlite": "^5.1.1",
"sqlite3": "^5.1.7",
"ts-node": "10.9.2",
"typescript": "^5.6.3",
"typescript-eslint": "^8.13.0"
Expand Down
2 changes: 1 addition & 1 deletion src/issue-activity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
import { ContextPlugin } from "./types/plugin-input";

export class IssueActivity {
private readonly _context: ContextPlugin;
protected readonly _context: ContextPlugin;
readonly _configuration: DataCollectionConfiguration;

constructor(
Expand Down
13 changes: 9 additions & 4 deletions src/parser/content-evaluator-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ export class ContentEvaluatorModule extends BaseModule {
);

if (Object.keys(relevancesByAi).length !== commentsToEvaluate.length + prCommentsToEvaluate.length) {
throw this.context.logger.fatal("Relevance / Comment length mismatch!", { relevancesByAi, commentsToEvaluate });
throw this.context.logger.fatal("Relevance / Comment length mismatch!", {
relevancesByAi,
commentsToEvaluate,
prCommentsToEvaluate,
});
}

for (const currentComment of commentsWithScore) {
Expand Down Expand Up @@ -231,9 +235,10 @@ export class ContentEvaluatorModule extends BaseModule {
return relevances;
} catch (e) {
throw new Error(
this.context.logger.error(
`Invalid response type received from openai while evaluating: ${jsonResponse} \n\nError: ${e}`
).logMessage.raw
this.context.logger.error(`Invalid response type received from openai while evaluating: \n\nError: ${e}`, {
error: e as Error,
jsonResponse,
}).logMessage.raw
);
}
}
Expand Down
79 changes: 43 additions & 36 deletions src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,52 @@ import { Result } from "./types/results";

export async function run(context: ContextPlugin) {
const { eventName, payload, logger, config } = context;
if (eventName === "issues.closed") {
if (payload.issue.state_reason !== "completed") {
return logger.info("Issue was not closed as completed. Skipping.").logMessage.raw;
}
if (!(await preCheck(context))) {
const result = logger.error("All linked pull requests must be closed to generate rewards.");
await postComment(context, result);
return result.logMessage.raw;
}
logger.debug("Will use the following configuration:", { config });

if (eventName !== "issues.closed") {
return logger.error(`${eventName} is not supported, skipping.`).logMessage.raw;
}

if (payload.issue.state_reason !== "completed") {
return logger.info("Issue was not closed as completed. Skipping.").logMessage.raw;
}

if (!(await preCheck(context))) {
const result = logger.error("All linked pull requests must be closed to generate rewards.");
await postComment(context, result);
return result.logMessage.raw;
}

logger.debug("Will use the following configuration:", { config });

if (config.incentives.githubComment?.post) {
await postComment(context, logger.ok("Evaluating results. Please wait..."));
const issue = parseGitHubUrl(payload.issue.html_url);
const activity = new IssueActivity(context, issue);
await activity.init();
if (config.incentives.requirePriceLabel && !getSortedPrices(activity.self?.labels).length) {
const result = logger.error("No price label has been set. Skipping permit generation.");
await postComment(context, result);
return result.logMessage.raw;
}
const processor = new Processor(context);
await processor.run(activity);
let result = processor.dump();
if (result.length > GITHUB_DISPATCH_PAYLOAD_LIMIT) {
logger.info("Truncating payload as it will trigger an error.");
const resultObject = JSON.parse(result) as Result;
for (const [key, value] of Object.entries(resultObject)) {
resultObject[key] = {
userId: value.userId,
task: value.task,
permitUrl: value.permitUrl,
total: value.total,
};
}
result = JSON.stringify(resultObject);
}

const issue = parseGitHubUrl(payload.issue.html_url);
const activity = new IssueActivity(context, issue);
await activity.init();
if (config.incentives.requirePriceLabel && !getSortedPrices(activity.self?.labels).length) {
const result = logger.error("No price label has been set. Skipping permit generation.");
await postComment(context, result);
return result.logMessage.raw;
}
const processor = new Processor(context);
await processor.run(activity);
let result = processor.dump();
if (result.length > GITHUB_DISPATCH_PAYLOAD_LIMIT) {
logger.info("Truncating payload as it will trigger an error.");
const resultObject = JSON.parse(result) as Result;
for (const [key, value] of Object.entries(resultObject)) {
resultObject[key] = {
userId: value.userId,
task: value.task,
permitUrl: value.permitUrl,
total: value.total,
};
}
return JSON.parse(result);
} else {
return logger.error(`${eventName} is not supported, skipping.`).logMessage.raw;
result = JSON.stringify(resultObject);
}
return JSON.parse(result);
}

async function preCheck(context: ContextPlugin) {
Expand Down
2 changes: 0 additions & 2 deletions src/types/plugin-input.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { StaticDecode, Type as T } from "@sinclair/typebox";
import { Context } from "@ubiquity-os/plugin-sdk";
import { LOG_LEVEL } from "@ubiquity-os/ubiquity-os-logger";
import { contentEvaluatorConfigurationType } from "../configuration/content-evaluator-config";
import { dataCollectionConfigurationType } from "../configuration/data-collection-config";
import { dataPurgeConfigurationType } from "../configuration/data-purge-config";
Expand All @@ -12,7 +11,6 @@ import { EnvConfig } from "./env-type";

export const pluginSettingsSchema = T.Object(
{
logLevel: T.Enum(LOG_LEVEL, { default: LOG_LEVEL.INFO }),
/**
* Network ID to run in, default to 100
*/
Expand Down
3 changes: 3 additions & 0 deletions src/types/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ export const LINKED_PULL_REQUESTS = /* GraphQL */ `
}
`;

/**
* Note: you cannot pass more than 100 node ids at once, otherwise the query will fail.
*/
export const QUERY_COMMENT_DETAILS = /* GraphQL */ `
query commentDetails($node_ids: [ID!]!) {
nodes(ids: $node_ids) {
Expand Down
2 changes: 2 additions & 0 deletions src/web/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist
db/database.db
12 changes: 12 additions & 0 deletions src/web/.ubiquity-os.config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# This file serves as a base to build a custom configuration

evmNetworkId: 100
incentives:
contentEvaluator: {}
userExtractor: {}
dataPurge: {}
formattingEvaluator: {}
permitGeneration: {}
githubComment:
post: false
debug: false
56 changes: 56 additions & 0 deletions src/web/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# @ubiquity-os/text-conversation-rewards-ui

This project provides a user interface for managing text conversation rewards. It includes several scripts for building, developing, and previewing the UI.

## Scripts

You can run the following scripts using `bun run <script>`:

- **server**: Starts the server with file watching.
- **ui:dev**: Starts the Vite development server.
- **ui:build**: Builds the production-ready UI bundle.
- **ui:build-watch**: Builds the UI bundle and watches for changes.
- **ui:preview**: Previews the built UI bundle.

## How to Get Started

1. **Install dependencies**: Make sure you have [Bun](https://bun.sh/) installed, then run:

```sh
bun install
```

2. **Start the server**:

```sh
bun run server
```

3. **Develop the UI**:

```sh
bun run ui:dev
```

4. **Build the UI for production**:

```sh
bun run ui:build
```

5. **Preview the built UI**:
```sh
bun run ui:preview
```

> [!WARNING]
> To see the changes you made on the UI when using the `server`, you need first to run `ui:build` as files are
> statically served.
### For Development

To develop the UI and see changes in real-time, use the `ui:dev` script. This will start a Vite development server which you can access in your browser.

### For Building and Previewing

When you're ready to build the UI for production, use the `ui:build` script. You can then use the `ui:preview` script to preview the built application.
Loading

0 comments on commit a5875e9

Please sign in to comment.