Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/question-example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Generate Question Examples

on:
pull_request:
branches: [ "main" ]
# paths:
# - 'public/docs/**'

jobs:
question-example:
runs-on: ubuntu-latest
# Push権限を付与
permissions:
contents: write

steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.head_ref }}
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci

- run: npx tsx ./scripts/questionExample.ts 4
env:
API_KEY: ${{ secrets.API_KEY }}

- name: Commit and Push changes
# 前のステップが成功・失敗どちらでも必ず実行
if: always()
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add .
git diff --staged --exit-code || (git commit -m "[ci] generate question examples" && git push)
101 changes: 43 additions & 58 deletions app/[lang]/[pageId]/chatForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,75 +27,60 @@ export function ChatForm({ path, sectionContent, close }: ChatFormProps) {

const { addChat } = useChatHistoryContext();

// const lang = getLanguageName(docs_id);

const { files, replOutputs, execResults } = useEmbedContext();

// const documentContentInView = sectionContent
// .filter((s) => s.inView)
// .map((s) => s.rawContent)
// .join("\n\n");
// const { data: exampleData, error: exampleError } = useSWR(
// // 質問フォームを開いたときだけで良い
// {
// lang,
// documentContent: documentContentInView,
// } satisfies QuestionExampleParams,
// getQuestionExample,
// {
// // リクエストは古くても構わないので1回でいい
// revalidateIfStale: false,
// revalidateOnFocus: false,
// revalidateOnReconnect: false,
// }
// );
// if (exampleError) {
// console.error("Error getting question example:", exampleError);
// }
const exampleData = sectionContent
.filter((s) => s.inView)
.map((s) => s.question)
.filter((qe) => qe !== undefined)
.flat();
// 質問フォームを開くたびにランダムに選び直し、
// exampleData[Math.floor(exampleChoice * exampleData.length)] を採用する
const [exampleChoice, setExampleChoice] = useState<number>(0); // 0〜1
const [exampleChoice, setExampleChoice] = useState<number | undefined>(
undefined
); // 0〜1
useEffect(() => {
if (exampleChoice === 0) {
if (exampleChoice === undefined) {
setExampleChoice(Math.random());
}
}, [exampleChoice]);

const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
setIsLoading(true);
setErrorMessage(null); // Clear previous error message
let userQuestion = inputValue;
if (!userQuestion && exampleData.length > 0 && exampleChoice) {
// 質問が空欄なら、質問例を使用
userQuestion =
exampleData[Math.floor(exampleChoice * exampleData.length)];
setInputValue(userQuestion);
}
if (userQuestion) {
e.preventDefault();
setIsLoading(true);
setErrorMessage(null); // Clear previous error message

const userQuestion = inputValue;
// if (!userQuestion && exampleData) {
// // 質問が空欄なら、質問例を使用
// userQuestion =
// exampleData[Math.floor(exampleChoice * exampleData.length)];
// setInputValue(userQuestion);
// }
const result = await askAI({
path,
userQuestion,
sectionContent,
replOutputs,
files,
execResults,
});

const result = await askAI({
path,
userQuestion,
sectionContent,
replOutputs,
files,
execResults,
});
if (result.error !== null) {
setErrorMessage(result.error);
console.log(result.error);
} else {
addChat(result.chat);
document.getElementById(result.chat.sectionId)?.scrollIntoView({
behavior: "smooth",
});
setInputValue("");
close();
}

if (result.error !== null) {
setErrorMessage(result.error);
console.log(result.error);
} else {
addChat(result.chat);
document.getElementById(result.chat.sectionId)?.scrollIntoView({
behavior: "smooth",
});
setInputValue("");
close();
setIsLoading(false);
}

setIsLoading(false);
};

return (
Expand All @@ -110,10 +95,10 @@ export function ChatForm({ path, sectionContent, close }: ChatFormProps) {
<textarea
className="textarea textarea-ghost textarea-md rounded-box"
placeholder={
"質問を入力してください" /* +
(exampleData
"質問を入力してください" +
(exampleData.length > 0 && exampleChoice !== undefined
? ` (例:「${exampleData[Math.floor(exampleChoice * exampleData.length)]}」)`
: "")*/
: "")
}
style={{
width: "100%",
Expand Down
2 changes: 1 addition & 1 deletion app/actions/chatActions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use server";

// import { z } from "zod";
import { generateContent } from "./gemini";
import { generateContent } from "@/lib/gemini";
import { DynamicMarkdownSection } from "../[lang]/[pageId]/pageContent";
import { ReplCommand, ReplOutput } from "@my-code/runtime/interface";
import { addChat, ChatWithMessages } from "@/lib/chatHistory";
Expand Down
42 changes: 0 additions & 42 deletions app/actions/questionExample.ts

This file was deleted.

24 changes: 14 additions & 10 deletions app/lib/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,25 @@ export interface PagePath {
}
export type SectionId = Brand<string, "SectionId">;

export interface MarkdownSection {
/**
* セクションのmdファイル名
*/
file: string;
export interface SectionFrontMatter {
/**
* frontmatterに書くセクションid
* (データベース上の sectionId)
*/
id: SectionId;
level: number;
title: string;
/**
* そのセクションに対する質問例
* scripts/questionExample.ts で生成する
*/
question?: string[];
}
export interface MarkdownSection extends SectionFrontMatter {
/**
* セクションのmdファイル名
*/
file: string;
/**
* frontmatterを除く、見出しも含めたもとのmarkdownの内容
*/
Expand Down Expand Up @@ -253,11 +260,7 @@ function parseFrontmatter(content: string, file: string): MarkdownSection {
if (endIdx === -1) {
throw new Error(`File ${file} has invalid frontmatter`);
}
const fm = yaml.load(content.slice(4, endIdx)) as {
id: SectionId;
title: string;
level: number;
};
const fm = yaml.load(content.slice(4, endIdx)) as SectionFrontMatter;
// TODO: validation of frontmatter using zod
// replコードブロックにはセクションidをターミナルidとして与える。
const rawContent = content
Expand All @@ -268,6 +271,7 @@ function parseFrontmatter(content: string, file: string): MarkdownSection {
id: fm.id,
title: fm.title,
level: fm.level,
question: fm.question,
rawContent,
md5: crypto.createHash("md5").update(rawContent).digest("base64"),
};
Expand Down
File renamed without changes.
4 changes: 4 additions & 0 deletions public/docs/cpp/0-intro/1-0-about.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
id: cpp-intro-about
title: C++とは?
level: 2
question:
- C++はC言語を拡張したとありますが、C言語とは何が違うのですか?
- なぜ他の言語ではなくC++を学ぶと良いのですか?
- パワフルで汎用性が高いとは、具体的にどのような意味ですか?
---

## C++とは?
Expand Down
6 changes: 6 additions & 0 deletions public/docs/cpp/0-intro/1-1-feature.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
id: cpp-intro-feature
title: 特徴
level: 3
question:
- 低レベルな操作とは具体的に何を指しますか?
- 実行速度が速いと、どのようなメリットがありますか?
- 静的型付けの反対は動的型付けですか?それらの違いは何ですか?
- マルチパラダイムとは、複数のプログラミングスタイルを自由に選べるということですか?
- オブジェクト指向プログラミングやジェネリックプログラミングとは何ですか?
---

### 特徴
Expand Down
5 changes: 5 additions & 0 deletions public/docs/cpp/0-intro/1-2-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
id: cpp-intro-usage
title: C++が使われる分野
level: 3
question:
- ゲーム開発やOS開発でC++が使われるのは、どの特徴が活かされているからですか?
- 金融システムで1ミリ秒を争うとは、具体的にどのような処理を指しますか?
- 組み込みシステムでリソースが限られているとはどういう意味ですか?
- C++を学ぶと、これらの分野で仕事ができるようになりますか?
---

### C++が使われる分野
Expand Down
4 changes: 4 additions & 0 deletions public/docs/cpp/0-intro/2-0-env-about.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
id: cpp-intro-env-about
title: 開発環境のセットアップ
level: 2
question:
- コンパイラがないとプログラムは実行できないのですか?
- ソースコードと機械語の違いは何ですか?
- ブラウザ上でコードが実行できるのに、ローカル環境のセットアップはなぜ必要ですか?
---

## 開発環境のセットアップ
Expand Down
5 changes: 5 additions & 0 deletions public/docs/cpp/0-intro/2-1-ide.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
id: cpp-intro-ide
title: コンパイラとIDE
level: 3
question:
- 複数のコンパイラがありますが、どれを使えば良いですか?
- IDEとエディタは同じものですか?それとも違いがありますか?
- Visual StudioとVisual Studio Codeは、名前が似ていますが何が違いますか?
- エラーメッセージが分かりやすいClangは初心者におすすめですか?
---

### コンパイラとIDE
Expand Down
5 changes: 5 additions & 0 deletions public/docs/cpp/0-intro/2-2-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
id: cpp-intro-setup
title: おすすめのセットアップ
level: 3
question:
- Visual Studio Communityは無料ですか?
- macOSでxcode-select --installを実行すると何がインストールされますか?
- Linuxのインストールコマンドは何をしていますか?
- Visual Studio Codeの拡張機能とは、具体的にどのようなものをインストールすれば良いですか?
---

### おすすめのセットアップ
Expand Down
4 changes: 4 additions & 0 deletions public/docs/cpp/0-intro/3-0-helloworld.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
id: cpp-intro-helloworld
title: 最初のプログラム
level: 2
question:
- なぜファイル名はmain.cppである必要があるのですか?他の名前ではだめですか?
- コードの各行が何をしているのかまだ理解できません。
- //は何のために使われていますか?
---

## 最初のプログラム
Expand Down
6 changes: 6 additions & 0 deletions public/docs/cpp/0-intro/3-1-run.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
id: cpp-intro-run
title: コンパイルと実行
level: 3
question:
- g++とclang++とclは、それぞれどのコンパイラを使うコマンドですか?
- '-o mainや/Fe:main.exeは何のために必要ですか?'
- コンパイルに失敗した場合、どのようなメッセージが表示されますか?
- なぜPythonやJavaScriptはコンパイルが不要なのですか?
- コンパイルすると、どのようなファイルが生成されますか?
---

### コンパイルと実行
Expand Down
3 changes: 3 additions & 0 deletions public/docs/cpp/0-intro/4-0-basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
id: cpp-intro-basic
title: C++の基本構造
level: 2
question:
- このセクションでは、コードの各部分について詳しく解説されるということですか?
- C++のプログラムは、常に同じような構造をしているのですか?
---

## C++の基本構造
Expand Down
6 changes: 6 additions & 0 deletions public/docs/cpp/0-intro/4-1-include.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
id: cpp-intro-include
title: '#include <iostream> - ヘッダファイルのインクルード'
level: 3
question:
- プリプロセッサ命令とは何ですか?
- iostreamがないとstd::coutは使えないのですか?
- ヘッダファイルとは何ですか?
- 自分で作成したヘッダファイルは、どのような場合に使うのですか?
- '#includeを書き忘れたらどうなりますか?'
---

### `#include <iostream>` - ヘッダファイルのインクルード
Expand Down
Loading