Skip to content

Commit

Permalink
Merge pull request #509 from refly-ai/sprint/v0.3.0
Browse files Browse the repository at this point in the history
Sprint/v0.3.0
  • Loading branch information
mrcfps authored Feb 14, 2025
2 parents 505c58a + 33b5b4a commit f9a096f
Show file tree
Hide file tree
Showing 149 changed files with 6,479 additions and 1,269 deletions.
1 change: 0 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"editor.formatOnSave": true,
"editor.defaultFormatter": "biomejs.biome",
"typescript.preferences.importModuleSpecifier": "non-relative",
"typescript.preferences.preferTypeOnlyAutoImports": true,
"tailwindCSS.includeLanguages": {
"typescript": "tsx",
"javascript": "jsx",
Expand Down
17 changes: 15 additions & 2 deletions apps/api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
# Base image
FROM node:20-alpine@sha256:b5b9467fe7b33aad47f1ec3f6e0646a658f85f05c18d4243024212a91f3b7554

# Install curl for healthcheck
RUN apk add --no-cache curl
# Install curl for healthcheck and pandoc dependencies
RUN apk add --no-cache curl gcompat

# Install pandoc based on architecture
ARG TARGETARCH

RUN if [ "$TARGETARCH" = "amd64" ]; then \
wget https://github.com/jgm/pandoc/releases/download/3.6.3/pandoc-3.6.3-linux-amd64.tar.gz \
&& tar xvzf pandoc-3.6.3-linux-amd64.tar.gz --strip-components 1 -C /usr/local/ \
&& rm pandoc-3.6.3-linux-amd64.tar.gz; \
elif [ "$TARGETARCH" = "arm64" ]; then \
wget https://github.com/jgm/pandoc/releases/download/3.6.3/pandoc-3.6.3-linux-arm64.tar.gz \
&& tar xvzf pandoc-3.6.3-linux-arm64.tar.gz --strip-components 1 -C /usr/local/ \
&& rm pandoc-3.6.3-linux-arm64.tar.gz; \
fi

WORKDIR /app

Expand Down
10 changes: 6 additions & 4 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
"@hocuspocus/extension-database": "~2.15.0",
"@hocuspocus/extension-redis": "~2.15.0",
"@hocuspocus/server": "~2.15.0",
"@langchain/community": "0.3.16",
"@langchain/core": "0.3.19",
"@langchain/openai": "0.3.14",
"@langchain/community": "0.3.29",
"@langchain/core": "0.3.29",
"@langchain/openai": "0.4.3",
"@nest-lab/throttler-storage-redis": "^1.0.0",
"@nestjs/bullmq": "~10.2.3",
"@nestjs/common": "~10.3.9",
Expand Down Expand Up @@ -61,9 +61,10 @@
"helmet": "^7.1.0",
"ioredis": "^5.4.1",
"jsonwebtoken": "~9.0.2",
"langchain": "0.3.6",
"langchain": "0.3.15",
"lodash": "^4.17.21",
"lru-cache": "^10.2.0",
"mime": "^3.0.0",
"minio": "7.1.3",
"module-alias": "~2.2.3",
"ms": "^2.1.3",
Expand All @@ -82,6 +83,7 @@
"reflect-metadata": "^0.1.13",
"resend": "^4.0.1",
"rxjs": "^7.2.0",
"sharp": "^0.33.5",
"stripe": "~14.19.0",
"uuid": "^9.0.1",
"ws": "~8.17.0",
Expand Down
59 changes: 35 additions & 24 deletions apps/api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -146,31 +146,33 @@ model ActionResult {

model ActionStep {
/// Primary key
pk BigInt @id @default(autoincrement())
pk BigInt @id @default(autoincrement())
/// Action result id which this step belongs to
resultId String @map("result_id")
resultId String @map("result_id")
/// Action result version
version Int @default(0) @map("version")
version Int @default(0) @map("version")
/// Step order
order Int @default(0) @map("order")
order Int @default(0) @map("order")
/// Step name
name String @map("name")
name String @map("name")
/// Step content
content String @map("content")
content String @map("content")
/// Step reasoning content
reasoningContent String? @map("reasoning_content")
/// Structured data output (JSON)
structuredData String @default("{}") @map("structured_data")
structuredData String @default("{}") @map("structured_data")
/// Action logs
logs String @default("[]") @map("logs")
logs String @default("[]") @map("logs")
/// Action artifacts (JSON array)
artifacts String @default("[]") @map("artifacts")
artifacts String @default("[]") @map("artifacts")
/// Token usage summary (JSON array)
tokenUsage String @default("[]") @map("token_usage")
tokenUsage String @default("[]") @map("token_usage")
/// Create timestamp
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz()
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz()
/// Update timestamp
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz()
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz()
/// Soft delete timestamp
deletedAt DateTime? @map("deleted_at") @db.Timestamptz()
deletedAt DateTime? @map("deleted_at") @db.Timestamptz()
@@index([resultId, version, order])
@@map("action_steps")
Expand Down Expand Up @@ -211,27 +213,34 @@ model TokenUsage {

model StaticFile {
/// Primary key
pk BigInt @id @default(autoincrement())
pk BigInt @id @default(autoincrement())
/// UID
uid String @map("uid")
uid String @map("uid")
/// Storage key
storageKey String @map("storage_key")
storageKey String @map("storage_key")
/// Storage size (in bytes)
storageSize BigInt @default(0) @map("storage_size")
storageSize BigInt @default(0) @map("storage_size")
/// Content type
contentType String @default("") @map("content_type")
/// Processed image storage key (only applicable to images)
processedImageKey String? @map("processed_image_key")
/// Entity id
entityId String? @map("entity_id")
entityId String? @map("entity_id")
/// Entity type
entityType String? @map("entity_type")
entityType String? @map("entity_type")
/// Visibility
visibility String @default("private") @map("visibility")
/// Expiration timestamp
expiredAt DateTime? @map("expired_at") @db.Timestamptz()
expiredAt DateTime? @map("expired_at") @db.Timestamptz()
/// Create timestamp
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz()
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz()
/// Update timestamp
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz()
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz()
/// Soft delete timestamp
deletedAt DateTime? @map("deleted_at") @db.Timestamptz()
deletedAt DateTime? @map("deleted_at") @db.Timestamptz()
@@index([uid, entityId, entityType])
@@index([entityId, entityType])
@@index([storageKey])
@@map("static_files")
}

Expand Down Expand Up @@ -302,6 +311,8 @@ model Resource {
storageSize BigInt @default(0) @map("storage_size")
/// Vector storage size (in bytes)
vectorSize BigInt @default(0) @map("vector_size")
/// Raw file storage key
rawFileKey String? @map("raw_file_key")
/// Index status
indexStatus String @default("init") @map("index_status")
/// Title
Expand Down
9 changes: 2 additions & 7 deletions apps/api/src/action/action.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
InvokeActionRequest,
ActionResult,
ActionStep,
ActionType,
Expand All @@ -14,14 +13,9 @@ import {
import { pick } from '@/utils';
import { modelInfoPO2DTO } from '@/misc/misc.dto';

export interface InvokeActionJobData extends InvokeActionRequest {
uid: string;
rawParam: string;
}

export function actionStepPO2DTO(step: ActionStepModel): ActionStep {
return {
...pick(step, ['name', 'content']),
...pick(step, ['name', 'content', 'reasoningContent']),
logs: JSON.parse(step.logs || '[]'),
artifacts: JSON.parse(step.artifacts || '[]'),
structuredData: JSON.parse(step.structuredData || '{}'),
Expand All @@ -37,6 +31,7 @@ export function actionResultPO2DTO(
type: result.type as ActionType,
tier: result.tier as ModelTier,
targetType: result.targetType as EntityType,
input: JSON.parse(result.input || '{}'),
actionMeta: JSON.parse(result.actionMeta || '{}'),
context: JSON.parse(result.context || '{}'),
tplConfig: JSON.parse(result.tplConfig || '{}'),
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class CustomThrottlerGuard extends ThrottlerGuard {
{
name: 'default',
ttl: seconds(1),
limit: 10,
limit: 50,
},
],
getTracker: (req) => (req.ips?.length ? req.ips[0] : req.ip),
Expand Down
12 changes: 11 additions & 1 deletion apps/api/src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,17 @@ export class AuthService {
let avatar: string;
try {
if (photos?.length > 0) {
avatar = (await this.miscService.dumpFileFromURL({ uid }, photos[0].value)).url;
avatar = (
await this.miscService.dumpFileFromURL(
{ uid },
{
url: photos[0].value,
entityId: uid,
entityType: 'user',
visibility: 'public',
},
)
).url;
}
} catch (e) {
this.logger.warn(`failed to download avatar: ${e}`);
Expand Down
27 changes: 21 additions & 6 deletions apps/api/src/canvas/canvas.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ import {
} from '@nestjs/common';
import { JwtAuthGuard } from '@/auth/guard/jwt-auth.guard';
import { CanvasService } from './canvas.service';
import { User as UserType } from '@prisma/client';
import { LoginedUser } from '@/utils/decorators/user.decorator';
import { canvasPO2DTO } from '@/canvas/canvas.dto';
import { buildSuccessResponse } from '@/utils';
import { UpsertCanvasRequest, DeleteCanvasRequest } from '@refly-packages/openapi-schema';
import {
User,
UpsertCanvasRequest,
DeleteCanvasRequest,
AutoNameCanvasRequest,
AutoNameCanvasResponse,
} from '@refly-packages/openapi-schema';

@Controller('v1/canvas')
export class CanvasController {
Expand All @@ -23,7 +28,7 @@ export class CanvasController {
@UseGuards(JwtAuthGuard)
@Get('list')
async listCanvases(
@LoginedUser() user: UserType,
@LoginedUser() user: User,
@Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number,
@Query('pageSize', new DefaultValuePipe(10), ParseIntPipe) pageSize: number,
) {
Expand All @@ -33,22 +38,32 @@ export class CanvasController {

@UseGuards(JwtAuthGuard)
@Post('create')
async createCanvas(@LoginedUser() user: UserType, @Body() body: UpsertCanvasRequest) {
async createCanvas(@LoginedUser() user: User, @Body() body: UpsertCanvasRequest) {
const canvas = await this.canvasService.createCanvas(user, body);
return buildSuccessResponse(canvasPO2DTO(canvas));
}

@UseGuards(JwtAuthGuard)
@Post('update')
async updateCanvas(@LoginedUser() user: UserType, @Body() body: UpsertCanvasRequest) {
async updateCanvas(@LoginedUser() user: User, @Body() body: UpsertCanvasRequest) {
const canvas = await this.canvasService.updateCanvas(user, body);
return buildSuccessResponse(canvasPO2DTO(canvas));
}

@UseGuards(JwtAuthGuard)
@Post('delete')
async deleteCanvas(@LoginedUser() user: UserType, @Body() body: DeleteCanvasRequest) {
async deleteCanvas(@LoginedUser() user: User, @Body() body: DeleteCanvasRequest) {
await this.canvasService.deleteCanvas(user, body);
return buildSuccessResponse({});
}

@UseGuards(JwtAuthGuard)
@Post('autoName')
async autoNameCanvas(
@LoginedUser() user: User,
@Body() body: AutoNameCanvasRequest,
): Promise<AutoNameCanvasResponse> {
const data = await this.canvasService.autoNameCanvas(user, body);
return buildSuccessResponse(data);
}
}
5 changes: 5 additions & 0 deletions apps/api/src/canvas/canvas.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ export interface DeleteCanvasNodesJobData {
entities: Entity[];
}

export interface AutoNameCanvasJobData {
uid: string;
canvasId: string;
}

export function canvasPO2DTO(canvas: CanvasModel): Canvas {
return {
...pick(canvas, ['canvasId', 'title', 'shareCode']),
Expand Down
13 changes: 11 additions & 2 deletions apps/api/src/canvas/canvas.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';
import { CanvasController } from './canvas.controller';
import { CanvasService } from './canvas.service';
import { ClearCanvasEntityProcessor, SyncCanvasEntityProcessor } from './canvas.processor';
import {
ClearCanvasEntityProcessor,
SyncCanvasEntityProcessor,
AutoNameCanvasProcessor,
} from './canvas.processor';
import { CollabModule } from '@/collab/collab.module';
import { QUEUE_DELETE_KNOWLEDGE_ENTITY } from '@/utils/const';
import { CommonModule } from '@/common/common.module';
Expand All @@ -18,7 +22,12 @@ import { MiscModule } from '@/misc/misc.module';
}),
],
controllers: [CanvasController],
providers: [CanvasService, SyncCanvasEntityProcessor, ClearCanvasEntityProcessor],
providers: [
CanvasService,
SyncCanvasEntityProcessor,
ClearCanvasEntityProcessor,
AutoNameCanvasProcessor,
],
exports: [CanvasService],
})
export class CanvasModule {}
26 changes: 24 additions & 2 deletions apps/api/src/canvas/canvas.processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@ import { Logger } from '@nestjs/common';
import { Job } from 'bullmq';

import { CanvasService } from './canvas.service';
import { QUEUE_CLEAR_CANVAS_ENTITY, QUEUE_SYNC_CANVAS_ENTITY } from '@/utils/const';
import { DeleteCanvasNodesJobData, SyncCanvasEntityJobData } from './canvas.dto';
import {
QUEUE_CLEAR_CANVAS_ENTITY,
QUEUE_SYNC_CANVAS_ENTITY,
QUEUE_AUTO_NAME_CANVAS,
} from '@/utils/const';
import {
DeleteCanvasNodesJobData,
SyncCanvasEntityJobData,
AutoNameCanvasJobData,
} from './canvas.dto';

@Processor(QUEUE_SYNC_CANVAS_ENTITY)
export class SyncCanvasEntityProcessor extends WorkerHost {
Expand Down Expand Up @@ -46,3 +54,17 @@ export class ClearCanvasEntityProcessor extends WorkerHost {
}
}
}

@Processor(QUEUE_AUTO_NAME_CANVAS)
export class AutoNameCanvasProcessor extends WorkerHost {
private logger = new Logger(AutoNameCanvasProcessor.name);

constructor(private canvasService: CanvasService) {
super();
}

async process(job: Job<AutoNameCanvasJobData>) {
this.logger.log(`Processing auto name canvas job ${job.id} for canvas ${job.data.canvasId}`);
await this.canvasService.autoNameCanvasFromQueue(job.data);
}
}
Loading

0 comments on commit f9a096f

Please sign in to comment.