-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
177 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,4 +46,4 @@ public | |
.eslintrc.*js | ||
.remarkrc.*js | ||
.env | ||
bun.lockb | ||
npm.lockb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"schemaVersion": 1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,12 +12,13 @@ | |
"author": "rdmclin2 <[email protected]>", | ||
"type": "module", | ||
"scripts": { | ||
"build": "bun scripts/build.ts", | ||
"test": "bun scripts/test.ts" | ||
"build": "npm scripts/build.ts", | ||
"test": "npm scripts/test.ts" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^20.10.4", | ||
"consola": "^3", | ||
"consola": "^3.0.0", | ||
"dayjs": "^1.11.10", | ||
"fs-extra": "^11", | ||
"lodash-es": "^4.17.21", | ||
"typescript": "^5", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,127 +1,87 @@ | ||
import { consola } from "consola"; | ||
import { readJSONSync, writeJSONSync } from "fs-extra"; | ||
import { merge } from "lodash-es"; | ||
import { Dirent, existsSync } from "node:fs"; | ||
import { Dirent } from "node:fs"; | ||
import { resolve } from "node:path"; | ||
import { zodToJsonSchema } from "zod-to-json-schema"; | ||
|
||
import { Parser } from "./Parser"; | ||
import { | ||
agents, | ||
config, | ||
localesDir, | ||
meta, | ||
publicDir, | ||
publicAgentDir, | ||
schemasDir, | ||
agentsDir, | ||
} from "./const"; | ||
import { VidolAgent } from "./schema/agent"; | ||
import { | ||
checkDir, | ||
checkJSON, | ||
findDuplicates, | ||
getLocaleAgentFileName, | ||
} from "./utils"; | ||
import { VidolAgent, VidolAgentSchema } from "./schema/agent"; | ||
import { checkDir, checkJSON } from "./utils"; | ||
import { formatAndCheckSchema } from "./check"; | ||
|
||
class Builder { | ||
private agents: Dirent[]; | ||
private dances: Dirent[]; | ||
|
||
constructor() { | ||
checkDir(publicDir); | ||
checkDir(publicAgentDir); | ||
this.agents = agents; | ||
this.dances = | ||
} | ||
|
||
/** | ||
* build single locale agents | ||
* @param locale | ||
*/ | ||
private buildSingleLocaleAgents = (locale: string) => { | ||
const agentIndex: VidolAgent[] = []; | ||
for (const file of this.agents) { | ||
// if file is not json ,skip it | ||
if (!checkJSON(file)) continue; | ||
const { | ||
content, | ||
locale: defaultLocale, | ||
id, | ||
} = Parser.parseFile(file.name); | ||
|
||
const localeFileName = getLocaleAgentFileName(id, locale); | ||
|
||
// find correct agent content | ||
let agent: VidolAgent; | ||
if (defaultLocale === locale) { | ||
agent = content; | ||
} else { | ||
// if locale agent is not exist, skip it | ||
const filePath = resolve(localesDir, localeFileName); | ||
if (!existsSync(filePath)) continue; | ||
|
||
// merge default agent with data | ||
const data = readJSONSync(filePath); | ||
agent = merge({}, content, data); | ||
} | ||
|
||
// write agent to public dir | ||
writeJSONSync(resolve(publicDir, localeFileName), agent); | ||
|
||
// add agent meta to index | ||
agentIndex.push({ | ||
author: agent.author, | ||
createAt: agent.createAt, | ||
homepage: agent.homepage, | ||
identifier: agent.identifier, | ||
meta: agent.meta, | ||
schemaVersion: agent.schemaVersion, | ||
}); | ||
} | ||
|
||
return agentIndex.sort( | ||
// @ts-ignore | ||
(a, b) => new Date(b.createAt) - new Date(a.createAt) | ||
); | ||
}; | ||
|
||
run = async () => { | ||
this.buildSchema(); | ||
await this.buildFullLocaleAgents(); | ||
await this.buildAgents(); | ||
}; | ||
|
||
buildSchema = () => { | ||
consola.start(`build agent schema`); | ||
checkDir(schemasDir); | ||
checkDir(resolve(publicDir, "schema")); | ||
|
||
const schema = zodToJsonSchema(lobeAgentSchema); | ||
const fileName = `lobeAgentSchema_v${meta.schemaVersion}.json`; | ||
const schema = zodToJsonSchema(VidolAgentSchema); | ||
const fileName = `vidolAgentSchema_v${meta.schemaVersion}.json`; | ||
writeJSONSync(resolve(schemasDir, fileName), schema); | ||
writeJSONSync(resolve(publicDir, "schema", fileName), schema); | ||
consola.success(`build success`); | ||
}; | ||
|
||
buildFullLocaleAgents = async () => { | ||
for (const locale of config.outputLocales) { | ||
consola.start(`build ${locale}`); | ||
buildAgents = async () => { | ||
consola.start(`build agents`); | ||
|
||
const agents = this.buildSingleLocaleAgents(locale); | ||
consola.info(`collected ${agents.length} agents`); | ||
const agentIndex: VidolAgent[] = []; | ||
for (const file of this.agents) { | ||
// if file is not json ,skip it | ||
if (!checkJSON(file)) continue; | ||
|
||
let tags = []; | ||
const [id] = file.name.split("."); | ||
const agent = readJSONSync(resolve(agentsDir, file.name)) as VidolAgent; | ||
|
||
agents.forEach((agent) => { | ||
tags = [...tags, ...agent.meta.tags]; | ||
}); | ||
// format and check schema | ||
const formatAgent = formatAndCheckSchema(agent); | ||
|
||
tags = findDuplicates(tags); | ||
// write agent to public dir | ||
writeJSONSync(resolve(publicAgentDir, file.name), formatAgent); | ||
|
||
const agentsIndex = { ...meta, tags, agents }; | ||
// write agent to agents dir | ||
writeJSONSync(resolve(agentsDir, file.name), formatAgent); | ||
|
||
const indexFileName = getLocaleAgentFileName("index", locale); | ||
writeJSONSync(resolve(publicDir, indexFileName), agentsIndex); | ||
consola.success(`build ${locale}`); | ||
// add agent meta to index | ||
agentIndex.push({ | ||
agentId: id, | ||
...formatAgent, | ||
}); | ||
} | ||
|
||
const agents = agentIndex.sort( | ||
// @ts-ignore | ||
(a, b) => new Date(b.createAt) - new Date(a.createAt) | ||
); | ||
|
||
consola.info(`collected ${agents.length} agents`); | ||
|
||
const agentsIndex = { ...meta, agents }; | ||
|
||
const indexFileName = "index.json"; | ||
writeJSONSync(resolve(publicAgentDir, indexFileName), agentsIndex); | ||
consola.success(`build complete`); | ||
}; | ||
} | ||
|
||
await new Builder(agents).run(); | ||
await new Builder().run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { consola } from "consola"; | ||
import dayjs from "dayjs"; | ||
|
||
import { meta } from "./const"; | ||
import { VidolAgentSchema } from "./schema/agent"; | ||
|
||
export const formatAndCheckSchema = (agent) => { | ||
if (!agent.schemaVersion) agent.schemaVersion = meta.schemaVersion; | ||
if (!agent.createAt) agent.createAt = dayjs().format("YYYY-MM-DD"); | ||
|
||
const result = VidolAgentSchema.safeParse(agent); | ||
|
||
if (result.success) { | ||
consola.success(`schema check pass`); | ||
} else { | ||
consola.error(`schema check fail`); | ||
throw new Error((result as any).error); | ||
} | ||
return agent; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { consola } from "consola"; | ||
import { readJSONSync } from "fs-extra"; | ||
import { resolve } from "node:path"; | ||
|
||
import { formatAndCheckSchema } from "./check"; | ||
import { agents, agentsDir, root } from "./const"; | ||
|
||
const runTest = () => { | ||
for (const file of agents) { | ||
if (file.isFile()) { | ||
const filePath = resolve(agentsDir, file.name); | ||
consola.start(filePath.replace(root, "")); | ||
const agent = readJSONSync(filePath); | ||
formatAndCheckSchema(agent); | ||
} | ||
} | ||
}; | ||
|
||
runTest(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { consola } from "consola"; | ||
import { colors } from "consola/utils"; | ||
import { Dirent, existsSync, mkdirSync, writeFileSync } from "node:fs"; | ||
|
||
import { readmeSplit } from "./const"; | ||
|
||
export const writeJSON = (filePath, data, format = true) => { | ||
const jsonStr = format ? JSON.stringify(data, null, 2) : JSON.stringify(data); | ||
writeFileSync(filePath, jsonStr, "utf8"); | ||
}; | ||
|
||
export const checkDir = (dirpath) => { | ||
if (!existsSync(dirpath)) mkdirSync(dirpath); | ||
}; | ||
|
||
export const checkJSON = (file: Dirent) => | ||
file.isFile() && file.name?.endsWith(".json"); | ||
|
||
export const split = (name) => { | ||
consola.log(""); | ||
consola.log( | ||
colors.gray( | ||
`========================== ${name} ==============================` | ||
) | ||
); | ||
}; | ||
|
||
export const findDuplicates = (arr: string[]): string[] => { | ||
const duplicates: { [key: string]: number } = {}; | ||
|
||
// 统计每个项目出现的次数 | ||
for (const item of arr) { | ||
if (duplicates[item]) { | ||
duplicates[item]++; | ||
} else { | ||
duplicates[item] = 1; | ||
} | ||
} | ||
|
||
// 挑出重复出现 3 次以上的项目 | ||
const COUNT = 3; | ||
|
||
const result = Object.keys(duplicates).filter( | ||
(item) => duplicates[item] >= COUNT | ||
); | ||
|
||
// 按重复次数从多到少排序 | ||
result.sort((a, b) => duplicates[b] - duplicates[a]); | ||
|
||
return result; | ||
}; | ||
|
||
export const updateAwesomeReadme = (md: string, prompts: string): string => { | ||
const mds = md.split(readmeSplit); | ||
mds[1] = [" ", prompts, " "].join("\n\n"); | ||
|
||
return mds.join(readmeSplit); | ||
}; | ||
|
||
export const checkHeader = (line: string) => { | ||
const header = [ | ||
"### systemRole", | ||
"### identifier", | ||
"### avatar", | ||
"### title", | ||
"### description", | ||
"### tags", | ||
"### locale", | ||
]; | ||
let check = false; | ||
header.forEach((item) => { | ||
if (line.startsWith(item)) check = true; | ||
}); | ||
return check; | ||
}; |
Oops, something went wrong.