Skip to content

Commit

Permalink
refactor: use abstract instead of implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
bytemain committed Aug 9, 2023
1 parent 3b6ddfe commit 9cf84ce
Show file tree
Hide file tree
Showing 15 changed files with 82 additions and 75 deletions.
6 changes: 3 additions & 3 deletions src/ai/conversation/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ChatGPTAPI, ChatMessage, SendMessageBrowserOptions } from 'chatgpt';

import Environment from '@/env';
import { IBotAdapter } from '@/im';
import { Context } from '@/im/commands';
import { DingBot } from '@/im/ding/bot';

import { ConversationKVManager } from './kvManager';

Expand All @@ -12,10 +12,10 @@ export class Conversation {

constructor(
protected currentRoundPrompt: string,
protected bot: DingBot,
protected bot: IBotAdapter,
protected ctx: Context,
) {
this.conversationId = bot.msg.conversationId;
this.conversationId = ctx.message.conversationId;
this.conversationKVManager = bot.conversationKVManager;
}

Expand Down
30 changes: 14 additions & 16 deletions src/api/controllers/ding.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DingBot, verifyMessage } from '@/im/ding/bot';
import { Session } from '@/im/bot';
import { DingBotAdapter, verifyMessage } from '@/im/ding/bot';
import { DingKVManager } from '@/kv/ding';
import { errorCallback } from '@/utils';

export function route(hono: THono) {
hono.post('/ding/:id', async (c) => {
Expand All @@ -21,7 +21,7 @@ export function route(hono: THono) {
if (!setting.outGoingToken) {
return c.send.error(
400,
`please set webhook token in database: ${kvManager.secretsKV.f(id)}`,
`please set webhook token in database: ${kvManager.secretsKV.f(id)}`,
);
}

Expand All @@ -34,22 +34,20 @@ export function route(hono: THono) {
return c.send.error(403, errMessage);
}

const bot = new DingBot(
id,
const session = new Session(
c,
await c.req.json(),
kvManager,
c.executionCtx,
setting,
new DingBotAdapter(
id,
c,
await c.req.json(),
kvManager,
c.executionCtx,
setting,
),
);

c.executionCtx.waitUntil(
errorCallback(bot.handle(), async (err: unknown) => {
await bot.replyText(
`处理消息出错: ${(err as Error).message} ${(err as Error).stack}`,
);
}),
);
session.runInBackground();

return c.send.message('ok');
});
}
2 changes: 1 addition & 1 deletion src/github/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class App {

octoApp: OctoApp<{ Octokit: typeof Octokit }>;

constructor(private setting: AppSetting) {
constructor(setting: AppSetting) {
const { appSettings, githubSecret } = setting;
Configuration.init(setting);

Expand Down
21 changes: 18 additions & 3 deletions src/im/bot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
import { IBotImpl } from './types';
import { Context } from 'hono';

export class Bot {
constructor(public impl: IBotImpl) {}
import { IBotAdapter } from './types';

export class Session {
constructor(public c: Context<THonoEnvironment>, public impl: IBotAdapter) {}

async run() {
await this.impl.handle().catch(async (err) => {
await this.impl.replyText(
`处理消息出错: ${(err as Error).message} ${(err as Error).stack}`,
);
throw err;
});
}

async runInBackground() {
this.c.executionCtx.waitUntil(this.run());
}
}
4 changes: 2 additions & 2 deletions src/im/commands/chatgpt.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { OpenAI } from '@/im/openai';

import { DingCommandCenter } from './types';
import { IMCommandCenter } from './types';

export function registerChatGPTCommand(it: DingCommandCenter) {
export function registerChatGPTCommand(it: IMCommandCenter) {
it.on('清除记忆', async ({ bot }) => {
await bot.conversationKVManager.clearConversation();
await bot.replyText('已清除记忆');
Expand Down
11 changes: 5 additions & 6 deletions src/im/commands/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import { startsWith } from '@/commander';
import { IDingInfo } from '@/kv/types';
import { StringBuilder } from '@/utils';

import type { DingBot } from '../ding/bot';
import { code } from '../message';

import { Context, DingCommandCenter } from './types';
import { IMCommandCenter } from './types';

export function registerCommonCommand(it: DingCommandCenter) {
export function registerCommonCommand(it: IMCommandCenter) {
it.on(
'putData',
async ({ bot, ctx }) => {
Expand All @@ -22,13 +21,13 @@ export function registerCommonCommand(it: DingCommandCenter) {
startsWith,
);

it.on('getGroupInfo', async ({ bot }) => {
it.on('getGroupInfo', async ({ bot, ctx }) => {
await bot.reply(
code(
'json',
JSON.stringify({
conversationId: bot.msg.conversationId,
senderCorpId: bot.msg.senderCorpId,
conversationId: ctx.message.conversationId,
senderCorpId: ctx.message.senderCorpId,
}),
),
);
Expand Down
16 changes: 8 additions & 8 deletions src/im/commands/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { App } from '@/github/app';
import { render } from '@/github/render';
import { contentToMarkdown, parseGitHubUrl } from '@/github/utils';

import type { DingBot } from '../ding/bot';
import { code, markdown } from '../message';
import { IBotAdapter } from '../types';

import { ISSUE_REGEX, REPO_REGEX } from './constants';
import { DingCommandCenter } from './types';
import { IMCommandCenter } from './types';
import { hasApp, replyIfAppNotDefined } from './utils';

export function registerGitHubCommand(it: DingCommandCenter) {
export function registerGitHubCommand(it: IMCommandCenter) {
it.on(REPO_REGEX, async ({ bot, ctx, result }) => {
await replyIfAppNotDefined(bot, ctx);
if (!hasApp(ctx)) {
Expand All @@ -31,7 +31,7 @@ export function registerGitHubCommand(it: DingCommandCenter) {
await bot.reply(
markdown(
`${full_name} Open Graph`,
`![](${bot.proxyThisUrl(
`![](${bot.getProxiedUrl(
`https://opengraph.githubassets.com/${makeid(16)}/${full_name}`,
)})`,
),
Expand Down Expand Up @@ -103,7 +103,7 @@ export function registerGitHubCommand(it: DingCommandCenter) {
await bot.reply(
markdown(
`${full_name} Open Graph`,
`![](${bot.proxyThisUrl(
`![](${bot.getProxiedUrl(
`https://opengraph.githubassets.com/${makeid(
16,
)}/${full_name}`,
Expand Down Expand Up @@ -148,7 +148,7 @@ export function registerGitHubCommand(it: DingCommandCenter) {
);
}

async function getDefaultRepo(bot: DingBot) {
async function getDefaultRepo(bot: IBotAdapter) {
const defaultRepo = await bot.kvManager.getDefaultRepo(bot.id);
if (!defaultRepo) {
await bot.replyText(
Expand All @@ -164,7 +164,7 @@ async function getDefaultRepo(bot: DingBot) {
// 2. star ide-startup -> opensumi/ide-startup
// 3. star microsoft/core -> microsoft/core
// 4. star microsoft core -> microsoft/core
async function getRepoInfoFromCommand(argv: string[], bot: DingBot) {
async function getRepoInfoFromCommand(argv: string[], bot: IBotAdapter) {
const defaultRepo = await bot.kvManager.getDefaultRepo(bot.id);
let owner, repo;
if (defaultRepo) {
Expand Down Expand Up @@ -208,7 +208,7 @@ function makeid(length: number) {
}

async function replyGitHubIssue(
bot: DingBot,
bot: IBotAdapter,
app: App,
owner: string,
repo: string,
Expand Down
4 changes: 2 additions & 2 deletions src/im/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { CommandCenter } from '@/commander';
import { registerCommonCommand } from './common';
import { registerGitHubCommand } from './github';
import { registerOpenSumiCommand } from './opensumi';
import { DingCommandCenter } from './types';
import { IMCommandCenter } from './types';

export const cc = new CommandCenter({
prefix: [''],
}) as DingCommandCenter;
}) as IMCommandCenter;

registerCommonCommand(cc);
registerGitHubCommand(cc);
Expand Down
8 changes: 4 additions & 4 deletions src/im/commands/opensumi.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { equalFunc } from '@/commander';
import { RC_WORKFLOW_FILE } from '@/constants/opensumi';

import { DingBot } from '../ding/bot';
import { markdown } from '../message';
import { IBotAdapter } from '../types';

import { KnownRepo } from './constants';
import { Context, DingCommandCenter } from './types';
import { Context, IMCommandCenter } from './types';
import { hasApp, replyIfAppNotDefined } from './utils';

/**
* 拦截本次请求
*/
async function repoIntercept(bot: DingBot, ctx: Context, repo: string) {
async function repoIntercept(bot: IBotAdapter, ctx: Context, repo: string) {
const defaultRepo = await bot.kvManager.getDefaultRepo(bot.id);
if (!defaultRepo) {
return true;
Expand All @@ -23,7 +23,7 @@ async function repoIntercept(bot: DingBot, ctx: Context, repo: string) {
return false;
}

export function registerOpenSumiCommand(it: DingCommandCenter) {
export function registerOpenSumiCommand(it: IMCommandCenter) {
it.on('deploy', async ({ bot, ctx }) => {
if (await repoIntercept(bot, ctx, KnownRepo.OpenSumi)) {
return;
Expand Down
12 changes: 4 additions & 8 deletions src/im/commands/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { CancellationToken } from '@opensumi/ide-utils/lib/cancellation';

import { CommandCenter, IArgv } from '@/commander';
import { IRegexResolveResult, IResolveResult } from '@/commander/types';
import { App } from '@/github/app';

import type { DingBot } from '../ding/bot';
import { Message } from '../types';
import { IBotAdapter, Message } from '../types';

export interface Context<T = any> {
message: Message;
Expand All @@ -18,9 +14,9 @@ export interface Context<T = any> {

export type ContextWithApp<T = any> = Required<Context<T>>;

interface DingCommandCenterContext {
bot: DingBot;
interface IMCommandCenterContext {
bot: IBotAdapter;
ctx: Context;
}

export type DingCommandCenter = CommandCenter<DingCommandCenterContext>;
export type IMCommandCenter = CommandCenter<IMCommandCenterContext>;
6 changes: 3 additions & 3 deletions src/im/commands/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DingBot } from '../ding/bot';
import { IBotAdapter } from '../types';

import { Context } from './types';

Expand All @@ -8,10 +8,10 @@ export function hasApp<T>(
return !!item.app;
}

export async function replyIfAppNotDefined(bot: DingBot, ctx: Context) {
export async function replyIfAppNotDefined(bot: IBotAdapter, ctx: Context) {
if (!hasApp(ctx)) {
await bot.replyText(
'Current DingBot has not configured use GitHub App. Please contact admin.',
'current bot has not configured use GitHub App. Please contact admin.',
);
}
}
8 changes: 4 additions & 4 deletions src/im/ding/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { IDingBotSetting } from '@/kv/types';

import { cc } from '../commands';
import { SendMessage, compose, text as textWrapper } from '../message';
import { Message } from '../types';
import { IBotAdapter, Message } from '../types';

function prepare(s: string) {
return s.toString().trim();
Expand Down Expand Up @@ -72,14 +72,14 @@ export async function verifyMessage(headers: Headers, token: string) {
}
}

export class DingBot {
export class DingBotAdapter implements IBotAdapter {
githubKVManager: GitHubKVManager;
conversationKVManager: ConversationKVManager;

constructor(
public id: string,
public c: Context<THonoEnvironment>,
public msg: Message,
protected msg: Message,
public kvManager: DingKVManager,
public ctx: ExecutionContext,
public setting: IDingBotSetting,
Expand Down Expand Up @@ -128,7 +128,7 @@ export class DingBot {
await send(content, this.msg.sessionWebhook);
}

proxyThisUrl(url: string) {
getProxiedUrl(url: string) {
return this.c.getProxiedUrl(url);
}
}
5 changes: 3 additions & 2 deletions src/im/openai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import throttle from 'lodash/throttle';

import { Conversation } from '@/ai/conversation';
import { Context } from '@/im/commands';
import { DingBot } from '@/im/ding/bot';
import { markdown } from '@/im/message';

import { IBotAdapter } from './types';

export class OpenAI {
constructor(
protected text: string,
protected bot: DingBot,
protected bot: IBotAdapter,
protected ctx: Context,
) {}

Expand Down
12 changes: 11 additions & 1 deletion src/im/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import type { ConversationKVManager } from '@/ai/conversation/kvManager';
import type { DingKVManager } from '@/kv/ding';

import { SendMessage } from './message';

export interface TextMessage {
Expand Down Expand Up @@ -58,7 +61,14 @@ export function isGroupMessage(message: any): message is GroupMessage {
);
}

export interface IBotImpl {
export interface IBotAdapter {
id: string;
kvManager: DingKVManager;
conversationKVManager: ConversationKVManager;

replyText(text: string, contentExtra?: Record<string, any>): Promise<void>;
reply(content: SendMessage): Promise<void>;
getProxiedUrl(url: string): string;

handle(): Promise<void>;
}
12 changes: 0 additions & 12 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,6 @@ export function randomChoice(arr: string[]) {
return arr[Math.floor(Math.random() * arr.length)];
}

export async function errorCallback(
promise: Promise<void>,
cb: (err: unknown) => void,
) {
try {
await promise;
} catch (err) {
cb(err);
throw err;
}
}

// format Date to "yyyy-mm-dd" style
export const formatDate = (date: Date) => {
const year = date.getFullYear();
Expand Down

0 comments on commit 9cf84ce

Please sign in to comment.