Skip to content

Commit

Permalink
update skeet ai mode
Browse files Browse the repository at this point in the history
  • Loading branch information
POPPIN-FUMI committed Sep 4, 2023
1 parent 3b85812 commit cb35d28
Show file tree
Hide file tree
Showing 52 changed files with 3,063 additions and 717 deletions.
31 changes: 31 additions & 0 deletions cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { execSync } from 'child_process'
import { writeFileSync } from 'fs'

// `$ skeet --help`からコマンドのリストを取得
function getCommands(): string[] {
const helpOutput = execSync('skeet --help').toString()

// 正規表現を使用してコマンド名を抽出 (これは仮の正規表現で、実際の出力に合わせて調整が必要です)
const commandMatches = helpOutput.match(/^\s*(\w+)\s+/gm)

if (!commandMatches) return []

return commandMatches.map((cmd) => cmd.trim())
}

// 各コマンドに対して詳細なヘルプを取得
function getDetailedHelpForCommand(command: string): string {
return execSync(`skeet ${command} --help`).toString()
}

// 実行
const commands = getCommands()
const detailedHelpArray: string[] = []

for (const command of commands) {
const detailedHelp = getDetailedHelpForCommand(command)
detailedHelpArray.push(detailedHelp)
}

writeFileSync('detailedHelpArray.txt', detailedHelpArray.join('\n\n'))
console.log(detailedHelpArray)
899 changes: 631 additions & 268 deletions dist/index.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"skeet:skeet": "yarn --cwd ./functions/skeet dev"
},
"dependencies": {
"@skeet-framework/ai": "^1.5.1",
"@skeet-framework/ai": "^1.6.0",
"@skeet-framework/utils": "1.2.1",
"chalk": "5.2.0",
"chalk-pipe": "6.0.0",
Expand Down Expand Up @@ -69,4 +69,4 @@
"tsconfig-paths": "4.2.0",
"typescript": "5.0.4"
}
}
}
2 changes: 1 addition & 1 deletion skeet-cloud.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"fbProjectId": "nextjs-graphql-394610"
},
"ai": {
"lang": "en",
"lang": "ja",
"ais": [
{
"name": "VertexAI",
Expand Down
160 changes: 91 additions & 69 deletions src/cli/ai/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
generatePrompt,
} from '@skeet-framework/ai'
import chalk from 'chalk'
import * as readline from 'readline'
import { skeetAiPrompt } from './skeetPrompt'
import { vertexStream } from './vertexStream'
import { openaiStream } from './openaiStream'
Expand All @@ -18,84 +17,107 @@ import { skeetMode } from './mode/skeetMode'
import { typedocMode } from './mode/typedocMode'
import { translateMode } from './mode/translateMode'
import { firestoreMode } from './mode/firestoreMode'

let rl: readline.Interface | null = null
import { functionMode } from './mode/functionMode'
import { log, logger } from '.'
import { SkeetAiMode, SkeetRole } from '@/types/skeetTypes'
import { methodMode } from './mode/methodMode'
import inquirer from 'inquirer'

export async function promptUser(options: SkeetAIOptions): Promise<void> {
if (!rl) {
rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})
}
const aiOptions = {
ai: (options.ai as AIType) || ('VertexAI' as AIType),
maxTokens: 1000,
model: options.model || 'chat-bison@001',
}
console.log('\n')
const userInput = await inquirer.prompt([
{
type: 'input',
name: 'input',
message:
chalk.white(`${log.common.start}\n`) +
chalk.green(`\n${log.common.you}:`),
},
])

rl.question(chalk.green('\nYou: '), async (input: string) => {
if (input.toLowerCase() === 'q') {
console.log(
chalk.white(`⭐️ ${chalk.blue(aiOptions.ai)} is shutting down...`)
)
rl?.close()
return
}
if (input.toLowerCase() === '') {
promptUser(aiOptions)
return
}
console.log(chalk.blue('Skeet:'))
const skeetAi = new SkeetAI(aiOptions)
if (userInput.input.toLowerCase() === 'q') {
console.log(
chalk.white(`⭐️ ${chalk.blue(aiOptions.ai)} ${log.common.shutdown}...`)
)
process.exit(0)
}
if (userInput.input.toLowerCase() === '') {
promptUser(aiOptions)
return
}
console.log(chalk.blue('Skeet:'))
const skeetAi = new SkeetAI(aiOptions)

if (input.toLowerCase().match(/^\$ prisma$/)) {
await prismaMode(skeetAi, rl!)
return
}
if (input.toLowerCase().match(/^\$ skeet/)) {
await skeetMode(input, skeetAi)
return
}
if (input.toLowerCase().match(/^\$ typedoc/)) {
await typedocMode(skeetAi, rl!)
return
}
if (input.toLowerCase().match(/^\$ translate/)) {
await translateMode(skeetAi, rl!)
promptUser(aiOptions)
return
}
if (input.toLowerCase().match(/^\$ firestore/)) {
await firestoreMode(skeetAi, rl!)
return
}
if (userInput.input.toLowerCase().match(/^\$ prisma$/)) {
await prismaMode(skeetAi)
return
}
if (userInput.input.toLowerCase().match(/^\$ skeet/)) {
await skeetMode(userInput.input, skeetAi)
return
}
if (userInput.input.toLowerCase().match(/^\$ typedoc/)) {
await typedocMode(skeetAi)
return
}
if (userInput.input.toLowerCase().match(/^\$ translate/)) {
await translateMode(skeetAi)
promptUser(aiOptions)
return
}
if (userInput.input.toLowerCase().match(/^\$ firestore/)) {
await firestoreMode(skeetAi)
return
}
if (userInput.input.toLowerCase().match(/^\$ function/)) {
await functionMode(skeetAi)
return
}
if (userInput.input.toLowerCase().match(/^\$ method/)) {
await methodMode(skeetAi)
return
}
if (userInput.input.toLowerCase().match(/^\$ help/)) {
logger.help()
promptUser(aiOptions)
return
}

const prompt = generatePrompt(
skeetAiPrompt.context,
skeetAiPrompt.examples,
input,
aiOptions.ai
)
const prompt = generatePrompt(
skeetAiPrompt.context,
skeetAiPrompt.examples,
userInput.input,
aiOptions.ai
)
logger.addJson(
SkeetRole.USER,
userInput.input,
SkeetAiMode.Skeet,
aiOptions.model
)

if (aiOptions.ai === 'VertexAI') {
try {
const ai = skeetAi.aiInstance as VertexAI
const stream = await ai.promptStream(prompt as VertexPromptParams)
vertexStream(stream, skeetAi.initOptions)
} catch (error) {
console.error('Error:', error)
rl?.close()
}
} else {
try {
const ai = skeetAi.aiInstance as OpenAI
const stream = await ai.promptStream(prompt as OpenAIPromptParams)
openaiStream(stream, skeetAi.initOptions)
} catch (error) {
console.error('Error:', error)
rl?.close()
}
if (aiOptions.ai === 'VertexAI') {
try {
const ai = skeetAi.aiInstance as VertexAI
const stream = await ai.promptStream(prompt as VertexPromptParams)
vertexStream(stream, skeetAi.initOptions)
} catch (error) {
console.error('Error:', error)
process.exit(1)
}
})
} else {
try {
const ai = skeetAi.aiInstance as OpenAI
const stream = await ai.promptStream(prompt as OpenAIPromptParams)
openaiStream(stream, skeetAi.initOptions)
} catch (error) {
console.error('Error:', error)
process.exit(1)
}
}
}
96 changes: 96 additions & 0 deletions src/cli/ai/aiLog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { SkeetAiMode } from '@/types/skeetTypes'
import { SkeetAIOptions } from '@skeet-framework/ai'
import { utcNow } from '@skeet-framework/utils'
import chalk from 'chalk'
import CliTable3 from 'cli-table3'
import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'fs'

export class AiLog {
lang: string

constructor(lang = 'en') {
this.lang = lang
}

text = () => {
const localeFile = JSON.parse(
readFileSync(`src/cli/ai/locales/${this.lang}/skeetAi.json`, 'utf8')
) as SkeetLog
return localeFile
}

help = () => {
console.log(
chalk.white(
`\n🤖 ${this.text().common.skeetAiModeText} 🤖\n\n` +
'$ prisma\n' +
'$ typedoc\n' +
'$ translate\n' +
'$ firestore\n' +
'$ function\n' +
'$ method\n' +
'$ help\n' +
'$ q\n'
)
)
}

aiOptionTable = (aiOptions: SkeetAIOptions) => {
const table = new CliTable3({
head: [chalk.blue('Option'), chalk.blue('Value')],
chars: {
top: '═',
'top-mid': '╤',
'top-left': '╔',
'top-right': '╗',
bottom: '═',
'bottom-mid': '╧',
'bottom-left': '╚',
'bottom-right': '╝',
left: '│',
'left-mid': '╟',
mid: '─',
'mid-mid': '┼',
right: '│',
'right-mid': '╢',
middle: '│',
}, // テーブルの罫線スタイルを指定
})

table.push(
[this.text().common.aiType, aiOptions.ai],
[this.text().common.model, aiOptions.model],
[this.text().common.maxToken, aiOptions.maxTokens],
[this.text().common.temperature, aiOptions.temperature]
)

console.log(table.toString())
}

addJson = (
role: string,
content: string,
mode: SkeetAiMode,
model: string
) => {
const tmpJson = `tmp/ai/history-${this.lang}.jsonl`
if (!existsSync('tmp/ai')) {
mkdirSync('tmp/ai', { recursive: true })
}
const data = {
role,
content,
mode,
model,
createdAt: utcNow(),
}
let insertData = ''
if (existsSync(tmpJson) === false) {
appendFileSync(tmpJson, '')
insertData = JSON.stringify(data)
} else {
insertData = ',\n' + JSON.stringify(data)
}
appendFileSync(tmpJson, insertData)
}
}
Loading

0 comments on commit cb35d28

Please sign in to comment.