From 845ed4aed30d867b0eb5ef9dc96a0cfaafc41060 Mon Sep 17 00:00:00 2001 From: chris Date: Mon, 20 Oct 2025 22:45:37 +0000 Subject: [PATCH] last fixes --- 10-ai-framework-project/README.md | 558 ++++- 8-code-editor/1-using-a-code-editor/README.md | 525 ++-- .../1-using-a-code-editor/assignment.md | 726 ++++-- 9-chat-project/README.md | 2136 +++++++++++++++-- .../solution/backend/python/README.md | 12 +- 9-chat-project/solution/backend/python/api.py | 86 +- 6 files changed, 3397 insertions(+), 646 deletions(-) diff --git a/10-ai-framework-project/README.md b/10-ai-framework-project/README.md index 3962b66d..cd0cdc25 100644 --- a/10-ai-framework-project/README.md +++ b/10-ai-framework-project/README.md @@ -1,16 +1,50 @@ # AI Framework -There are many AI frameworks out there that when used can severely quicken up the time it takes to build a project. In this project we will focus on understanding what problems these frameworks address and build such a project ourselves. +AI frameworks are powerful tools that can dramatically accelerate your development process when building intelligent applications. Think of an AI framework as a comprehensive toolkit that provides pre-built components, standardized APIs, and intelligent abstractions to help you focus on solving problems rather than wrestling with low-level implementation details. -## Why a framework +In this lesson, you'll discover how frameworks like LangChain can transform complex AI integration tasks into manageable, readable code. You'll learn to handle real-world challenges like maintaining conversation context, implementing tool calling, and managing different AI models through a unified interface. -When it comes to using AI there are different approaches and different reasons for choosing these approaches, here are some: +By the end of this project, you'll understand when to choose frameworks over direct API calls, how to leverage their abstractions effectively, and how to build production-ready AI applications with confidence. Let's explore the world of AI frameworks and unlock their potential for your projects! -- **No SDK**, most AI models allows you to interact directly with the AI model via for example HTTP requests. That approach works and may sometimes be your only option if an SDK option is missing. -- **SDK**. Using an SDK is usually the recommended approach as it allows you to type less code to interact with your model. It usually is limited to a specific model and if using different models, you might need to write new code to support those additional models. -- **A framework**. A framework usually takes things to another level in the sense that if you need to use different models, there's one API for all of them, what differs is usually the initial set up. Additionally frameworks brings in useful abstractions like in the AI space, they can deal with tools, memory, workflows, agents and more while writing less code. Because frameworks are usually opinionated they can really be helpful if you buy into how they do things but may fall short if you try to do something bespoke that the framework isn't made for. Sometimes a framework can also simplify too much and you may therefore not learn an important topic that later may harm performance for example. +## Why choose a framework? -Generally, use the right tool for the job. +When building AI applications, you have several integration approaches available, each with distinct advantages and trade-offs. Understanding these options helps you make informed architectural decisions for your projects. + +Let's explore the three main approaches to AI integration: + +| Approach | Advantages | Best For | Considerations | +|----------|------------|----------|--------------| +| **Direct HTTP Requests** | Full control, no dependencies | Simple queries, learning fundamentals | More verbose code, manual error handling | +| **SDK Integration** | Less boilerplate, model-specific optimization | Single-model applications | Limited to specific providers | +| **AI Frameworks** | Unified API, built-in abstractions | Multi-model apps, complex workflows | Learning curve, potential over-abstraction | + +### Framework Benefits in Practice + +```mermaid +graph TD + A[Your Application] --> B[AI Framework] + B --> C[OpenAI GPT] + B --> D[Anthropic Claude] + B --> E[GitHub Models] + B --> F[Local Models] + + B --> G[Built-in Tools] + G --> H[Memory Management] + G --> I[Conversation History] + G --> J[Function Calling] + G --> K[Error Handling] +``` + +**Key framework advantages:** +- **Unifies** multiple AI providers under a single API +- **Handles** conversation memory and context automatically +- **Provides** built-in tools for common tasks like embeddings and function calling +- **Manages** error handling and retry logic +- **Abstracts** complex workflows into simple method calls + +> πŸ’‘ **Pro Tip**: Choose frameworks when you need to switch between different AI models or implement complex features like agents, memory, or tool calling. Use direct APIs when you're learning fundamentals or building simple, single-purpose integrations. + +**Remember**: Use the right tool for the job. Frameworks excel at complex, multi-feature applications, while direct APIs work well for simple, focused use cases. ## Introduction @@ -20,13 +54,13 @@ In this lesson, we'll learn to: - Address common problems like chat conversations, tool usage, memory and context. - Leverage this to build AI apps. -## First prompt +## Your first AI prompt -In our first app example, we'll learn how to connect to an AI model and query it using a prompt. +Let's start with the fundamentals by creating a simple AI application that sends a prompt and receives a response. This example demonstrates how frameworks simplify what would otherwise require complex HTTP request handling. -### Using Python +### Setting up LangChain with GitHub Models -For this example, we'll use Langchain to connect to GitHub Models. We can use a class called `ChatOpenAI` and give it the fields `api_key`, `base_url` and `model`. The token is something that automatically is populated within GitHub Codespaces and if you're running the app locally, you need to set up a personal access token for this to work. +We'll use LangChain to connect to GitHub Models, which provides free access to various AI models. The setup requires just a few configuration parameters: ```python from langchain_openai import ChatOpenAI @@ -38,32 +72,59 @@ llm = ChatOpenAI( model="openai/gpt-4o-mini", ) -# works -response = llm.invoke("What's the capital of France?") +# Send a simple prompt +response = llm.invoke("What's the capital of France?") print(response.content) ``` -In this code, we: +**Here's what this code accomplishes:** +- **Creates** a LangChain client using the `ChatOpenAI` class +- **Configures** the connection to GitHub Models with your authentication token +- **Specifies** the AI model (`gpt-4o-mini`) for processing requests +- **Sends** a prompt using the `invoke()` method +- **Extracts** and displays the response content -- Call `ChatOpenAI` to create a client. -- Use `llm.invoke` with a prompt to create a response -- Print the response with `print(response.content)`. - -You should see a response similar to: +> πŸ”§ **Setup Note**: In GitHub Codespaces, the `GITHUB_TOKEN` environment variable is automatically available. For local development, you'll need to create a personal access token with appropriate permissions. +**Expected output:** ```text The capital of France is Paris. ``` -## Chat conversation +```mermaid +sequenceDiagram + participant App as Your Python App + participant LC as LangChain + participant GM as GitHub Models + participant AI as GPT-4o-mini + + App->>LC: llm.invoke("What's the capital of France?") + LC->>GM: HTTP request with prompt + GM->>AI: Process prompt + AI->>GM: Generated response + GM->>LC: Return response + LC->>App: response.content +``` -In the preceding section, you saw how we used what's normally known as zero shot prompting, a single prompt followed by a response. +## Building conversational AI -However, often you find yourself in a situation where you need to maintain a conversation of several messages being exchanged between yourself and the AI assistant. +The previous example demonstrated zero-shot promptingβ€”a single question with a single response. However, most real-world AI applications require maintaining context across multiple exchanges, just like human conversations. -### Using Python +LangChain provides message types that help structure conversations and define AI personality, making it easy to build sophisticated chat experiences. -In langchain, we can store the conversation in a list. The `HumanMessage` represents a message from a user, and `SystemMessage` is a message meant to set the "personality" of the AI. In below example you see how we instruct the AI to assume the personality of Captain Picard and for the human/user to ask "Tell me about you" as the prompt. +### Understanding message types + +LangChain uses different message classes to represent conversation participants: + +| Message Type | Purpose | Example Use Case | +|--------------|---------|------------------| +| `SystemMessage` | Defines AI personality and behavior | "You are a helpful coding assistant" | +| `HumanMessage` | Represents user input | "Explain how functions work" | +| `AIMessage` | Stores AI responses | Previous AI responses in conversation | + +### Creating your first conversation + +Let's build a conversation where the AI adopts a specific personality: ```python messages = [ @@ -72,6 +133,11 @@ messages = [ ] ``` +**Breaking down this conversation setup:** +- **Establishes** the AI's role and personality through `SystemMessage` +- **Provides** the initial user query via `HumanMessage` +- **Creates** a foundation for multi-turn conversation + The full code for this example looks like so: ```python @@ -155,15 +221,117 @@ I'll take that as a maybe ;) ## Streaming responses -TODO +Streaming responses provide real-time feedback as the AI generates content, creating a more interactive user experience similar to ChatGPT's typing effect. Instead of waiting for the complete response, you receive content as it's generated. + +### Implementing streaming with LangChain + +```python +from langchain_openai import ChatOpenAI +import os + +llm = ChatOpenAI( + api_key=os.environ["GITHUB_TOKEN"], + base_url="https://models.github.ai/inference", + model="openai/gpt-4o-mini", + streaming=True +) + +# Stream the response +for chunk in llm.stream("Write a short story about a robot learning to code"): + print(chunk.content, end="", flush=True) +``` + +**Key streaming concepts:** +- **Enables** real-time content delivery as the AI generates responses +- **Improves** user experience with immediate feedback +- **Reduces** perceived latency for longer responses +- **Allows** early response processing and display + +> πŸ’‘ **User Experience Tip**: Streaming is particularly valuable for longer responses like code explanations, creative writing, or detailed tutorials where users benefit from seeing progress immediately. ## Prompt templates -TODO +Prompt templates help you create reusable, dynamic prompts by separating the structure from the variable content. Think of them as mad-libs for AI promptsβ€”you define the template once and fill in different values as needed. + +### Creating reusable prompts + +```python +from langchain_core.prompts import ChatPromptTemplate + +# Define a template for code explanations +template = ChatPromptTemplate.from_messages([ + ("system", "You are an expert programming instructor. Explain concepts clearly with examples."), + ("human", "Explain {concept} in {language} with a practical example for {skill_level} developers") +]) + +# Use the template with different values +questions = [ + {"concept": "functions", "language": "JavaScript", "skill_level": "beginner"}, + {"concept": "classes", "language": "Python", "skill_level": "intermediate"}, + {"concept": "async/await", "language": "JavaScript", "skill_level": "advanced"} +] + +for question in questions: + prompt = template.format_messages(**question) + response = llm.invoke(prompt) + print(f"Topic: {question['concept']}\n{response.content}\n---\n") +``` + +**Template benefits in practice:** +- **Standardizes** prompt structure across your application +- **Enables** dynamic content insertion without string manipulation +- **Maintains** consistent AI behavior and output quality +- **Simplifies** prompt maintenance and updates ## Structured output -TODO +Structured output ensures AI responses follow a specific format, making them easier to parse and integrate into your applications. Instead of free-form text, you can request JSON, specific data structures, or formatted responses. + +### Defining output schemas + +```python +from langchain_core.prompts import ChatPromptTemplate +from langchain_core.output_parsers import JsonOutputParser +from pydantic import BaseModel, Field + +class CodeReview(BaseModel): + score: int = Field(description="Code quality score from 1-10") + strengths: list[str] = Field(description="List of code strengths") + improvements: list[str] = Field(description="List of suggested improvements") + overall_feedback: str = Field(description="Summary feedback") + +# Set up the parser +parser = JsonOutputParser(pydantic_object=CodeReview) + +# Create prompt with format instructions +prompt = ChatPromptTemplate.from_messages([ + ("system", "You are a code reviewer. {format_instructions}"), + ("human", "Review this code: {code}") +]) + +# Format the prompt with instructions +chain = prompt | llm | parser + +# Get structured response +code_sample = """ +def calculate_average(numbers): + return sum(numbers) / len(numbers) +""" + +result = chain.invoke({ + "code": code_sample, + "format_instructions": parser.get_format_instructions() +}) + +print(f"Score: {result['score']}") +print(f"Strengths: {', '.join(result['strengths'])}") +``` + +**Structured output advantages:** +- **Guarantees** consistent response format for reliable parsing +- **Enables** direct integration with databases and APIs +- **Validates** AI responses against predefined schemas +- **Simplifies** error handling and data processing ## Tool calling @@ -355,20 +523,340 @@ if(res.tool_calls): print("CONTENT: ",res.content) ``` -## Embedding +## Embeddings and document processing -vectorize content, compare via cosine similarity +Embeddings transform text into numerical vectors that capture semantic meaning, enabling similarity searches, content clustering, and retrieval-augmented generation (RAG). Think of embeddings as converting text into coordinates in a multi-dimensional space where similar meanings cluster together. -https://python.langchain.com/docs/how_to/embed_text/ +### Creating and using embeddings -### document loaders +```python +from langchain_openai import OpenAIEmbeddings +from langchain_community.vectorstores import FAISS +from langchain_community.document_loaders import TextLoader +from langchain.text_splitter import CharacterTextSplitter + +# Initialize embeddings +embeddings = OpenAIEmbeddings( + api_key=os.environ["GITHUB_TOKEN"], + base_url="https://models.github.ai/inference", + model="text-embedding-3-small" +) -pdf and csv +# Load and split documents +loader = TextLoader("documentation.txt") +documents = loader.load() -## Building an app +text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) +texts = text_splitter.split_documents(documents) -TODO +# Create vector store +vectorstore = FAISS.from_documents(texts, embeddings) -## Assignment +# Perform similarity search +query = "How do I handle user authentication?" +similar_docs = vectorstore.similarity_search(query, k=3) + +for doc in similar_docs: + print(f"Relevant content: {doc.page_content[:200]}...") +``` + +### Document loaders for various formats + +```python +from langchain_community.document_loaders import ( + PyPDFLoader, + CSVLoader, + JSONLoader, + WebBaseLoader +) + +# Load different document types +pdf_loader = PyPDFLoader("manual.pdf") +csv_loader = CSVLoader("data.csv") +json_loader = JSONLoader("config.json") +web_loader = WebBaseLoader("https://example.com/docs") + +# Process all documents +all_documents = [] +for loader in [pdf_loader, csv_loader, json_loader, web_loader]: + docs = loader.load() + all_documents.extend(docs) +``` + +**Embedding use cases:** +- **Powers** semantic search across your content +- **Enables** question-answering over your documents +- **Supports** content recommendation systems +- **Facilitates** automatic document categorization + +## Building a complete AI application + +Now let's combine everything you've learned into a practical AI application. We'll create a coding assistant that can answer questions, execute tools, and maintain conversation context. + +### Complete application example + +```python +from langchain_openai import ChatOpenAI, OpenAIEmbeddings +from langchain_core.prompts import ChatPromptTemplate +from langchain_core.messages import HumanMessage, SystemMessage, AIMessage +from langchain_community.vectorstores import FAISS +from typing_extensions import Annotated, TypedDict +import os +import requests + +class CodingAssistant: + def __init__(self): + self.llm = ChatOpenAI( + api_key=os.environ["GITHUB_TOKEN"], + base_url="https://models.github.ai/inference", + model="openai/gpt-4o-mini" + ) + + self.conversation_history = [ + SystemMessage(content="""You are an expert coding assistant. + Help users learn programming concepts, debug code, and write better software. + Use tools when needed and maintain a helpful, encouraging tone.""") + ] + + # Define tools + self.setup_tools() + + def setup_tools(self): + class web_search(TypedDict): + """Search for programming documentation or examples.""" + query: Annotated[str, "Search query for programming help"] + + class code_formatter(TypedDict): + """Format and validate code snippets.""" + code: Annotated[str, "Code to format"] + language: Annotated[str, "Programming language"] + + self.tools = [web_search, code_formatter] + self.llm_with_tools = self.llm.bind_tools(self.tools) + + def chat(self, user_input: str): + # Add user message to conversation + self.conversation_history.append(HumanMessage(content=user_input)) + + # Get AI response + response = self.llm_with_tools.invoke(self.conversation_history) + + # Handle tool calls if any + if response.tool_calls: + for tool_call in response.tool_calls: + tool_result = self.execute_tool(tool_call) + print(f"πŸ”§ Tool used: {tool_call['name']}") + print(f"πŸ“Š Result: {tool_result}") + + # Add AI response to conversation + self.conversation_history.append(response) + + return response.content + + def execute_tool(self, tool_call): + tool_name = tool_call['name'] + args = tool_call['args'] + + if tool_name == 'web_search': + return f"Found documentation for: {args['query']}" + elif tool_name == 'code_formatter': + return f"Formatted {args['language']} code: {args['code'][:50]}..." + + return "Tool execution completed" + +# Usage example +assistant = CodingAssistant() + +print("πŸ€– Coding Assistant Ready! Type 'quit' to exit.\n") + +while True: + user_input = input("You: ") + if user_input.lower() == 'quit': + break + + response = assistant.chat(user_input) + print(f"πŸ€– Assistant: {response}\n") +``` + +**Application architecture:** + +```mermaid +graph TD + A[User Input] --> B[Coding Assistant] + B --> C[Conversation Memory] + B --> D[Tool Detection] + B --> E[LLM Processing] + + D --> F[Web Search Tool] + D --> G[Code Formatter Tool] + + E --> H[Response Generation] + F --> H + G --> H + + H --> I[User Interface] + H --> C +``` + +**Key features implemented:** +- **Maintains** conversation context across multiple exchanges +- **Integrates** tool calling for enhanced functionality +- **Provides** structured interaction patterns +- **Handles** complex workflows with proper error management + +## Assignment: Build your own AI-powered study assistant + +**Objective**: Create an AI application that helps students learn programming concepts by providing explanations, code examples, and interactive quizzes. + +### Requirements + +**Core Features (Required):** +1. **Conversational Interface**: Implement a chat system that maintains context across multiple questions +2. **Educational Tools**: Create at least two tools that help with learning: + - Code explanation tool + - Concept quiz generator +3. **Personalized Learning**: Use system messages to adapt responses to different skill levels +4. **Response Formatting**: Implement structured output for quiz questions + +### Implementation Steps + +**Step 1: Setup your environment** +```bash +pip install langchain langchain-openai +``` + +**Step 2: Basic chat functionality** +- Create a `StudyAssistant` class +- Implement conversation memory +- Add personality configuration for educational support + +**Step 3: Add educational tools** +- **Code Explainer**: Breaks down code into understandable parts +- **Quiz Generator**: Creates questions about programming concepts +- **Progress Tracker**: Keeps track of topics covered + +**Step 4: Enhanced features (Optional)** +- Implement streaming responses for better user experience +- Add document loading to incorporate course materials +- Create embeddings for similarity-based content retrieval + +### Evaluation Criteria + +| Feature | Excellent (4) | Good (3) | Satisfactory (2) | Needs Work (1) | +|---------|---------------|----------|------------------|----------------| +| **Conversation Flow** | Natural, context-aware responses | Good context retention | Basic conversation | No memory between exchanges | +| **Tool Integration** | Multiple useful tools working seamlessly | 2+ tools implemented correctly | 1-2 basic tools | Tools not functional | +| **Code Quality** | Clean, well-documented, error handling | Good structure, some documentation | Basic functionality works | Poor structure, no error handling | +| **Educational Value** | Truly helpful for learning, adaptive | Good learning support | Basic explanations | Limited educational benefit | + +### Sample code structure + +```python +class StudyAssistant: + def __init__(self, skill_level="beginner"): + # Initialize LLM, tools, and conversation memory + pass + + def explain_code(self, code, language): + # Tool: Explain how code works + pass + + def generate_quiz(self, topic, difficulty): + # Tool: Create practice questions + pass + + def chat(self, user_input): + # Main conversation interface + pass + +# Example usage +assistant = StudyAssistant(skill_level="intermediate") +response = assistant.chat("Explain how Python functions work") +``` + +**Bonus Challenges:** +- Add voice input/output capabilities +- Implement a web interface using Streamlit or Flask +- Create a knowledge base from course materials using embeddings +- Add progress tracking and personalized learning paths ## Summary + +Congratulations! You've mastered the fundamentals of AI framework development and learned how to build sophisticated AI applications using LangChain. Let's review the key concepts and skills you've acquired. + +### What you've learned + +**Core Framework Concepts:** +- **Framework Benefits**: Understanding when to choose frameworks over direct API calls +- **LangChain Basics**: Setting up and configuring AI model connections +- **Message Types**: Using `SystemMessage`, `HumanMessage`, and `AIMessage` for structured conversations + +**Advanced Features:** +- **Tool Calling**: Creating and integrating custom tools for enhanced AI capabilities +- **Conversation Memory**: Maintaining context across multiple conversation turns +- **Streaming Responses**: Implementing real-time response delivery +- **Prompt Templates**: Building reusable, dynamic prompts +- **Structured Output**: Ensuring consistent, parseable AI responses +- **Embeddings**: Creating semantic search and document processing capabilities + +**Practical Applications:** +- **Building Complete Apps**: Combining multiple features into production-ready applications +- **Error Handling**: Implementing robust error management and validation +- **Tool Integration**: Creating custom tools that extend AI capabilities + +### Key takeaways + +> 🎯 **Remember**: AI frameworks like LangChain excel at abstracting complexity while providing powerful features. They're ideal for applications requiring conversation memory, tool calling, or multi-model support. + +**Decision framework for AI integration:** + +```mermaid +flowchart TD + A[AI Integration Need] --> B{Simple single query?} + B -->|Yes| C[Direct API calls] + B -->|No| D{Need conversation memory?} + D -->|No| E[SDK Integration] + D -->|Yes| F{Need tools or complex features?} + F -->|No| G[Framework with basic setup] + F -->|Yes| H[Full framework implementation] + + C --> I[HTTP requests, minimal dependencies] + E --> J[Provider SDK, model-specific] + G --> K[LangChain basic chat] + H --> L[LangChain with tools, memory, agents] +``` + +### Next steps in your AI journey + +**Immediate applications:** +- Apply these concepts to build your own AI-powered applications +- Experiment with different AI models through the unified LangChain interface +- Create tools that solve real problems in your domain + +**Advanced topics to explore:** +- **AI Agents**: Building autonomous AI systems that can plan and execute tasks +- **Retrieval-Augmented Generation (RAG)**: Combining AI with your own knowledge bases +- **Multi-Modal AI**: Working with text, images, and audio in unified applications +- **Production Deployment**: Scaling AI applications with proper monitoring and error handling + +**Community and resources:** +- Join the LangChain community for latest updates and best practices +- Explore GitHub Models for access to cutting-edge AI capabilities +- Practice with different use cases to deepen your understanding + +You're now equipped with the knowledge to build intelligent, conversational applications that can truly assist users in meaningful ways. The future of AI development is in your hands! + +## GitHub Copilot Agent Challenge πŸš€ + +Use the Agent mode to complete the following challenge: + +**Description:** Build an advanced AI-powered code review assistant that combines multiple LangChain features including tool calling, structured output, and conversation memory to provide comprehensive feedback on code submissions. + +**Prompt:** Create a CodeReviewAssistant class that implements: +1. A tool for analyzing code complexity and suggesting improvements +2. A tool for checking code against best practices +3. Structured output using Pydantic models for consistent review format +4. Conversation memory to track review sessions +5. A main chat interface that can handle code submissions and provide detailed, actionable feedback + +The assistant should be able to review code in multiple programming languages, maintain context across multiple code submissions in a session, and provide both summary scores and detailed improvement suggestions. diff --git a/8-code-editor/1-using-a-code-editor/README.md b/8-code-editor/1-using-a-code-editor/README.md index 8f73792b..9f9c36e8 100644 --- a/8-code-editor/1-using-a-code-editor/README.md +++ b/8-code-editor/1-using-a-code-editor/README.md @@ -1,164 +1,361 @@ - - -*** - -# Using a Code Editor: Mastering [VSCode.dev](https://vscode.dev) - -**Welcome!** -This lesson takes you from the basics to advanced use of [VSCode.dev](https://vscode.dev)β€”the powerful, web-based code editor. You’ll learn how to confidently edit code, manage projects, track changes, install extensions, and collaborate like a proβ€”all from your browser, with zero installation required. - -*** - -## Learning Objectives - -By the end of this lesson, you’ll be able to: - -- Efficiently use a code editor on any project, anywhere -- Seamlessly track your work with built-in version control -- Personalize and boost your development workflow with editor customizations and extensions - -*** - -## Prerequisites - -To get started, **sign up for a free [GitHub](https://github.com) account**, which lets you manage code repositories and collaborate worldwide. If you don’t have an account yet, [create one here](https://github.com/). - -*** - -## Why Use a Web-based Code Editor? - -A **code editor** like VSCode.dev is your command center for writing, editing, and managing code. With an intuitive interface, tons of features, and immediate access via the browser, you can: - -- Edit projects on any device -- Avoid the hassle of installations -- Collaborate and contribute instantly - -Once you’re comfortable with VSCode.dev, you’ll be prepared to tackle coding tasks from anywhere, anytime. - -*** - -## Getting Started with VSCode.dev - -Navigate to **[VSCode.dev](https://vscode.dev)**β€”no install, no downloads. Signing in with GitHub unlocks full access, including syncing your settings, extensions, and repositories. If prompted, connect your GitHub account. - -After loading, your workspace will look like this: - -![Default VSCode.dev](../images/default-vscode-dev has three core sections from left to right: -- **Activity bar:** The icons such as πŸ”Ž (Search), βš™οΈ (Settings), files, source control, etc. -- **Sidebar:** Changes context based on the activity bar icon selected (defaults to *Explorer* to show files). -- **Editor/code area:** The largest section to the rightβ€”where you’ll actually edit and view code. - -Click through the icons to explore features, but return to the _Explorer_ to keep your place. - -*** - -## Opening a GitHub Repository - -### Method 1: From the Editor - -1. Go to [VSCode.dev](https://vscode.dev). Click **"Open Remote Repository."** - - ![Open remote repository](../images/open-remote-repository use the _Command Palette_ (Ctrl-Shift-P, or Cmd-Shift-P on Mac). - - ![Palette Menu](../images/palette-menu.pngopen remote repository.” - - Select the option. - - Paste your GitHub repo URL (e.g., `https://github.com/microsoft/Web-Dev-For-Beginners`) and hit Enter. - -If successful, you’ll see the entire project loaded and ready to edit! - -*** - -### Method 2: Instantly via URL - -Transform any GitHub repo URL to open directly in VSCode.dev by replacing `github.com` with `vscode.dev/github`. -E.g.: - -- GitHub: `https://github.com/microsoft/Web-Dev-For-Beginners` -- VSCode.dev: `https://vscode.dev/github/microsoft/Web-Dev-For-Beginners` - -This feature supercharges quick access to ANY project. - -*** - -## Editing Files in Your Project - -Once your repo is open, you can: - -### 1. **Create a New File** -- In the *Explorer* sidebar, navigate to your desired folder or use the root. -- Click the _β€˜New file ...’_ icon. -- Name your file, press **Enter**, and your file appears instantly. - -![Create a new file](../images/create-new-file 2. **Edit and Save Files** - -- Click on a file in the *Explorer* to open it in the code area. -- Make your changes as needed. -- VSCode.dev automatically saves your changes, but you can press Ctrl+S to save manually. - -![Edit a file](../images/edit-a-file.png. **Track & Commit Changes with Version Control** - -VSCode.dev has integrated **Git** version control! - -- Click the _'Source Control'_ icon to view all changes made. -- Files in the `Changes` folder show additions (green) and deletions (red). - ![View changes](../images/working-tree.png changes by clicking the `+` next to files to prepare for commit. -- **Discard** unwanted changes by clicking the undo icon. -- Type a clear commit message, then click the checkmark to commit and push. - -To return to your repository on GitHub, select the hamburger menu at the top left. - -![Stage & commit changes](../images/edit-vscode.dev Up with Extensions - -Extensions let you add languages, themes, debuggers, and productivity tools to VSCode.devβ€”making your coding life easier and more fun. - -### Browsing and Managing Extensions - -- Click the **Extensions icon** on the activity bar. -- Search for an extension in the _'Search Extensions in Marketplace'_ box. - - ![Extension details](../images/extension-details: - - **Installed**: All extensions you’ve added - - **Popular**: Industry favorites - - **Recommended**: Tailored to your workflow - - ![View extensions]( - - - -*** - -### 1. **Install Extensions** - -- Enter the extension’s name in search, click it, and review details in the editor. -- Hit the **blue Install button** in the sidebar _or_ in the main code area. - - ![Install extensions](../images/install-extension 2. **Customize Extensions** - -- Find your installed extension. -- Click the **Gear icon** β†’ select _Extension Settings_ to fine-tune behaviors to your liking. - - ![Modify extension settings](../images/extension-settings 3. **Manage Extensions** -You can: - -- **Disable:** Temporarily turn off an extension while keeping it installed -- **Uninstall:** Permanently remove it if no longer needed - - Find the extension, hit the Gear icon, and select β€˜Disable’ or β€˜Uninstall,’ or use the blue buttons in the code area. - -*** - -## Assignment - -Test your skills: [Create a resume website using vscode.dev](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/8-code-editor/1-using-a-code-editor/assignment.md) - -*** - -## Further Exploration and Self-Study - -- Dive deeper with [the official VSCode Web Docs](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza). -- Explore advanced workspace features, keyboard shortcuts, and settings. - -*** - -**Now you’re ready to code, create, and collaborateβ€”from anywhere, on any device, using VSCode.dev!** - +# Using a Code Editor: Mastering VSCode.dev + +Welcome to the world of web-based code editing! In this lesson, you'll discover how to use VSCode.dev, a powerful browser-based code editor that brings professional development tools directly to your web browser. Think of it as having a complete development environment that follows you everywhere – no downloads, no installations, just pure coding power at your fingertips. + +Modern web development requires tools that are flexible, accessible, and powerful. VSCode.dev delivers all three by providing the same editing experience you'd get from a desktop application, but with the convenience of running entirely in your browser. This means you can code on any device, from anywhere, whether you're using a school computer, a friend's laptop, or even a tablet. + +By the end of this lesson, you'll be confidently editing code, managing projects, tracking changes with version control, and customizing your development environment with extensions. These skills form the foundation of professional web development and will serve you throughout your coding journey. + +## Learning Objectives + +After completing this lesson, you'll be able to: + +- Navigate and efficiently use VSCode.dev's interface for any coding project +- Open and edit GitHub repositories directly in your browser +- Track and commit changes using built-in Git version control +- Install and manage extensions to enhance your development workflow +- Create, edit, and organize files within web-based projects + +## Prerequisites + +Before starting this lesson, you'll need: + +- A free [GitHub account](https://github.com) for managing code repositories and accessing VSCode.dev's full features +- Basic familiarity with web browsers and file management +- Completion of the GitHub Basics lesson (recommended) + +> πŸ’‘ **Getting Started**: If you don't have a GitHub account yet, [create one here](https://github.com/). It's free and essential for modern web development collaboration! + +## Understanding Web-Based Code Editors + +A code editor serves as your primary workspace for writing, editing, and managing code. Unlike simple text editors, professional code editors provide syntax highlighting, error detection, file organization, and integration with development tools. VSCode.dev brings all these capabilities to your browser with several key advantages. + +**Key benefits of web-based editing:** + +| Benefit | Description | Impact | +|---------|-------------|---------| +| **Device Independence** | Works on any computer with a modern browser | Code from school, home, or anywhere | +| **Zero Setup** | No downloads or installations required | Start coding immediately | +| **Automatic Updates** | Always runs the latest version | Access newest features without manual updates | +| **Cloud Integration** | Direct connection to GitHub repositories | Seamless collaboration and backup | + +**Here's why web-based editors are revolutionary:** +- **Eliminates** the traditional barrier of software installation +- **Provides** consistent experience across different devices and operating systems +- **Enables** instant collaboration and sharing with team members +- **Reduces** storage requirements on your local device + +## Getting Started with VSCode.dev + +Let's dive into VSCode.dev and explore its powerful interface. This web-based editor provides all the tools you need for professional development work, accessible through any modern web browser. + +To begin, navigate to [vscode.dev](https://vscode.dev) in your browser. Notice that there's no download prompt or installation process – the editor loads directly in your browser tab. + +### Connecting Your GitHub Account + +For the best experience, sign in with your GitHub account when prompted. This connection unlocks powerful features including repository access, settings synchronization, and extension management. + +**Signing in provides these benefits:** +- **Accesses** your GitHub repositories directly in the editor +- **Synchronizes** your settings and extensions across devices +- **Enables** direct commits and pull requests from the browser +- **Maintains** your personalized development environment + +### Understanding the Interface + +Once loaded, VSCode.dev presents a clean, organized workspace designed for efficient coding: + +![Default VSCode.dev interface](../images/default-vscode-dev.png) + +**The interface consists of three main areas:** +- **Activity Bar** (left edge): Contains icons for Explorer πŸ“, Search πŸ”, Source Control 🌿, Extensions 🧩, and Settings βš™οΈ +- **Sidebar** (left panel): **Displays** contextual information based on your Activity Bar selection +- **Editor Area** (main space): **Provides** the primary workspace for viewing and editing your code files + +**Getting familiar with the layout:** +- **Click** through different Activity Bar icons to explore available features +- **Observe** how the sidebar content changes based on your selection +- **Return** to the Explorer view (πŸ“) to see your project files and folders + +## Opening GitHub Repositories + +One of VSCode.dev's most powerful features is its ability to open and edit GitHub repositories directly in your browser. This means you can contribute to projects, make quick fixes, or explore codebases without cloning anything to your local machine. + +There are two efficient methods to open repositories, each suited for different workflows and use cases. + +### Method 1: Using the Interface + +This method works well when you're already in VSCode.dev and want to open a specific repository: + +**Step-by-step process:** + +1. **Navigate** to [vscode.dev](https://vscode.dev) in your browser +2. **Click** the "Open Remote Repository" button on the welcome screen + + ![Open remote repository](../images/open-remote-repository.png) + +3. **Paste** your GitHub repository URL (for example: `https://github.com/microsoft/Web-Dev-For-Beginners`) +4. **Press** Enter to load the repository + +**Alternative using Command Palette:** + +For a faster approach, use the Command Palette (Ctrl+Shift+P on Windows/Linux, or Cmd+Shift+P on Mac): + +![Command Palette](../images/palette-menu.png) + +**Here's what happens when you use the Command Palette:** +- **Opens** a search interface for all available VSCode.dev commands +- **Provides** quick access to "Open Remote Repository" functionality +- **Enables** keyboard-driven workflow for experienced developers +- **Displays** recently opened repositories for quick access + +### Method 2: Direct URL Transformation + +This method offers the fastest way to open any GitHub repository directly in VSCode.dev. It's perfect for quick edits or when someone shares a repository link with you. + +**URL transformation technique:** + +| Repository Type | Original GitHub URL | VSCode.dev URL | +|----------------|---------------------|----------------| +| **Public Repository** | `github.com/microsoft/Web-Dev-For-Beginners` | `vscode.dev/github/microsoft/Web-Dev-For-Beginners` | +| **Your Repository** | `github.com/your-username/my-project` | `vscode.dev/github/your-username/my-project` | +| **Forked Repository** | `github.com/your-username/forked-repo` | `vscode.dev/github/your-username/forked-repo` | + +**Understanding the transformation:** +- **Replaces** `github.com` with `vscode.dev/github` in any repository URL +- **Maintains** the same path structure for user and repository names +- **Works** with both public repositories and private ones you have access to +- **Provides** instant access without additional navigation steps + +> πŸ’‘ **Pro Tip**: Bookmark the VSCode.dev version of repositories you frequently edit. This creates instant access to your most important projects! + +**When to use each method:** +- **Interface method**: Best for browsing and exploring new repositories +- **URL transformation**: Ideal for quick access to known repositories or when clicking links from documentation + +## Working with Files and Projects + +Once you have a repository open in VSCode.dev, you can perform all the essential file operations needed for web development. The interface provides intuitive tools for creating, editing, organizing, and tracking changes to your code. + +Let's explore the core file management capabilities that make VSCode.dev a complete development environment. + +### Creating New Files + +Adding new files to your project is straightforward and supports all common web development file types including HTML, CSS, JavaScript, and configuration files. + +**To create a new file:** + +1. **Navigate** to your desired folder location in the Explorer sidebar +2. **Click** the "New File" icon (πŸ“„+) that appears when hovering over folder names +3. **Type** your filename including the appropriate extension (e.g., `style.css`, `script.js`, `index.html`) +4. **Press** Enter to create the file + +![Creating a new file](../images/create-new-file.png) + +**Best practices for file creation:** +- **Uses** descriptive names that clearly indicate the file's purpose +- **Includes** proper file extensions for syntax highlighting and IntelliSense +- **Organizes** files into logical folder structures from the start +- **Follows** common naming conventions (lowercase, hyphens instead of spaces) + +### Editing and Saving Files + +VSCode.dev provides a full-featured editing experience with syntax highlighting, auto-completion, and error detection for web development languages. + +**Editing workflow:** + +1. **Click** any file in the Explorer to open it in the main editor area +2. **Make** your changes using the full-featured code editor +3. **Save** your work using Ctrl+S (Windows/Linux) or Cmd+S (Mac) + +![Editing files in VSCode.dev](../images/edit-a-file.png) + +**Key editing features:** +- **Provides** syntax highlighting for HTML, CSS, JavaScript, and many other languages +- **Offers** intelligent code completion and suggestions as you type +- **Detects** errors and provides helpful error messages +- **Supports** multiple files open simultaneously in tabs +- **Includes** automatic saving that preserves your work as you type + +> ⚠️ **Auto-Save Note**: VSCode.dev automatically saves your changes, but manually saving (Ctrl+S or Cmd+S) ensures your work is immediately preserved and triggers additional features like error checking. + +### Version Control with Git + +One of VSCode.dev's most powerful features is its integrated Git version control system. This allows you to track changes, create commits, and push updates directly to GitHub without leaving your browser. + +**Understanding the Source Control interface:** + +1. **Click** the Source Control icon (🌿) in the Activity Bar to view all changes +2. **Review** modified files, which appear in the "Changes" section +3. **See** additions highlighted in green and deletions in red + +![Viewing changes in Source Control](../images/working-tree.png) + +**The commit workflow:** + +```mermaid +flowchart TD + A[Make changes to files] --> B[View changes in Source Control] + B --> C[Stage changes by clicking +] + C --> D[Write descriptive commit message] + D --> E[Click checkmark to commit] + E --> F[Changes pushed to GitHub] +``` + +**Step-by-step commit process:** +- **Stages** individual files by clicking the "+" icon next to each changed file +- **Reviews** all staged changes before committing +- **Writes** a clear, descriptive commit message explaining what changed +- **Commits** and pushes changes by clicking the checkmark button +- **Discards** unwanted changes using the undo icon if needed + +**Writing effective commit messages:** +- **Describes** what the commit accomplishes in present tense +- **Keeps** the first line under 50 characters for readability +- **Uses** specific action verbs like "Add", "Fix", "Update", or "Remove" +- **Examples**: "Add responsive navigation menu", "Fix mobile layout issues", "Update color scheme for accessibility" + +> πŸ’‘ **Navigation Tip**: Use the hamburger menu (☰) at the top left to return to your GitHub repository and see your committed changes online. + +## Enhancing Your Workflow with Extensions + +Extensions are one of VSCode.dev's most powerful features, allowing you to customize and enhance your development environment. Think of extensions as specialized tools that add new capabilities, from language support and themes to debugging tools and productivity enhancers. + +The VSCode extension marketplace contains thousands of community-created tools designed to make web development more efficient, enjoyable, and powerful. By carefully selecting extensions, you can create a personalized development environment tailored to your specific needs and projects. + +### Discovering and Managing Extensions + +The Extensions marketplace in VSCode.dev provides easy access to tools that can transform your coding experience. The interface is designed to help you find exactly what you need, whether you're looking for specific functionality or browsing for inspiration. + +**Accessing the Extensions marketplace:** + +1. **Click** the Extensions icon (🧩) in the Activity Bar +2. **Browse** the different categories or use the search functionality +3. **Explore** extension details, ratings, and user reviews + +![Extension marketplace interface](../images/extensions.png) + +**Understanding extension categories:** + +| Category | Purpose | Examples | +|----------|---------|----------| +| **Installed** | Extensions you've already added | Your personal toolkit | +| **Popular** | Most-downloaded extensions | Industry standards and favorites | +| **Recommended** | Suggestions based on your workspace | Tailored to your current project type | + +**Key marketplace features:** +- **Displays** detailed information including ratings, download counts, and user reviews +- **Provides** screenshots and documentation for each extension +- **Shows** compatibility information and system requirements +- **Offers** related extensions and alternatives for comparison + +### Installing Extensions + +Adding new functionality to VSCode.dev is straightforward and immediate. Extensions install quickly and become available right away, often without requiring a restart. + +**Installation process:** + +1. **Search** for your desired extension using keywords or exact names +2. **Click** on the extension to view its details page +3. **Review** the description, features, and user ratings +4. **Click** the blue "Install" button + +![Installing extensions](../images/install-extension.gif) + +**What happens during installation:** +- **Downloads** the extension files to your browser-based environment +- **Integrates** new features into the VSCode.dev interface +- **Activates** the extension automatically for immediate use +- **Syncs** with your GitHub account so the extension appears on other devices + +**Recommended extensions for web development:** +- **Live Server**: **Provides** local development server with auto-refresh +- **Prettier**: **Formats** your code automatically for consistency +- **Auto Rename Tag**: **Updates** matching HTML tags simultaneously +- **Bracket Pair Colorizer**: **Highlights** matching brackets with colors +- **GitLens**: **Enhances** Git capabilities with advanced history and blame features + +### Customizing Extension Settings + +Most extensions provide customization options that allow you to tailor their behavior to match your workflow preferences. These settings help you optimize each tool for maximum productivity. + +**Accessing extension settings:** + +1. **Locate** your installed extension in the Extensions panel +2. **Click** the gear icon (βš™οΈ) next to the extension name +3. **Select** "Extension Settings" from the dropdown menu +4. **Modify** settings according to your preferences + +![Customizing extension settings](../images/extension-settings.png) + +**Common customization options:** +- **Adjusts** formatting rules and style preferences +- **Configures** keyboard shortcuts and trigger behaviors +- **Sets** file type associations and language preferences +- **Enables** or disables specific features within the extension + +### Managing Your Extension Collection + +As you discover more extensions, you'll want to organize and manage your collection effectively. VSCode.dev provides tools to help you maintain a clean, efficient development environment. + +**Extension management options:** + +| Action | Purpose | When to Use | +|--------|---------|-------------| +| **Disable** | Temporarily turn off without uninstalling | Testing conflicts or reducing clutter | +| **Uninstall** | Permanently remove from your environment | Extension no longer needed | +| **Update** | Get the latest version and features | Maintain security and functionality | + +**Best practices for extension management:** +- **Reviews** your installed extensions periodically to remove unused ones +- **Keeps** extensions updated for the latest features and security patches +- **Disables** rather than uninstalls extensions you might use again +- **Reads** extension changelogs to understand new features and changes + +> ⚠️ **Performance Tip**: While extensions are powerful, installing too many can impact performance. Focus on extensions that genuinely improve your workflow and disable any you're not actively using. + +## GitHub Copilot Agent Challenge πŸš€ + +Use the Agent mode to complete the following challenge: + +**Description:** Create a comprehensive development workflow using VSCode.dev that demonstrates professional project management skills, from repository setup to collaborative features. + +**Prompt:** Set up a complete web development project in VSCode.dev that includes: +1. Fork an existing repository or create a new one +2. Create a proper project structure with HTML, CSS, and JavaScript files +3. Install and configure at least 3 relevant extensions for web development +4. Make meaningful commits with descriptive messages +5. Create a feature branch and make changes +6. Document your workflow in a README.md file that explains your development process + +Your final project should demonstrate mastery of VSCode.dev's interface, extension ecosystem, and version control integration. + +## Assignment + +Ready to put your new skills to the test? Complete this hands-on project: [Create a resume website using VSCode.dev](./assignment.md) + +This assignment will guide you through creating a professional resume website entirely within your browser, demonstrating all the concepts covered in this lesson. + +## Further Exploration and Self-Study + +Continue building your expertise with these resources: + +**Official Documentation:** +- [VSCode Web Documentation](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) - Comprehensive guide to web-based editing +- [GitHub Codespaces](https://docs.github.com/en/codespaces) - Advanced cloud development environments + +**Advanced Features to Explore:** +- **Keyboard Shortcuts**: Learn efficiency-boosting shortcuts for faster development +- **Workspace Settings**: Customize your environment for different project types +- **Multi-root Workspaces**: Work with multiple repositories simultaneously +- **Terminal Integration**: Access command-line tools directly in your browser + +**Practice Suggestions:** +- **Contribute** to open-source projects using VSCode.dev +- **Experiment** with different extensions to find your optimal workflow +- **Create** templates for common project types you work on +- **Practice** Git workflows including branching, merging, and pull requests + +--- + +**Congratulations!** You now have the skills to code professionally from anywhere, on any device, using VSCode.dev. This browser-based development environment opens up new possibilities for flexible, collaborative web development. Whether you're working on personal projects, contributing to open source, or collaborating with a team, you're equipped with a powerful, accessible development workflow. \ No newline at end of file diff --git a/8-code-editor/1-using-a-code-editor/assignment.md b/8-code-editor/1-using-a-code-editor/assignment.md index 91f677c7..5425ff0d 100644 --- a/8-code-editor/1-using-a-code-editor/assignment.md +++ b/8-code-editor/1-using-a-code-editor/assignment.md @@ -1,252 +1,576 @@ -# Create a resume-website using vscode.dev +# Create a Resume Website Using VSCode.dev -_How cool would it be to have a recruiter ask for your resume and you send them a url?_ 😎 +Transform your career prospects by building a professional resume website that showcases your skills and experience in an interactive, modern format. Instead of sending traditional PDFs, imagine providing recruiters with a sleek, responsive website that demonstrates both your qualifications and your web development capabilities. - +This hands-on assignment puts all your VSCode.dev skills into practice while creating something genuinely useful for your career. You'll experience the complete web development workflow – from repository creation to deployment – all within your browser. - +By completing this project, you'll have a professional online presence that can be easily shared with potential employers, updated as your skills grow, and customized to match your personal brand. This is exactly the kind of practical project that demonstrates real-world web development skills. -## Objectives +## Learning Objectives -After this assignment, you'll learn how to: +After completing this assignment, you'll be able to: -- Create a website to showcase your resume +- **Create** and manage a complete web development project using VSCode.dev +- **Structure** a professional website using semantic HTML elements +- **Style** responsive layouts with modern CSS techniques +- **Implement** interactive features using basic web technologies +- **Deploy** a live website accessible via a shareable URL +- **Demonstrate** version control best practices throughout the development process -### Prerequisites +## Prerequisites -1. A GitHub account. Navigate to [GitHub](https://github.com/) and create an account if you haven't already. +Before starting this assignment, ensure you have: -## Steps +- A GitHub account (create one at [github.com](https://github.com/) if needed) +- Completion of the VSCode.dev lesson covering interface navigation and basic operations +- Basic understanding of HTML structure and CSS styling concepts -**Step 1:** Create a new GitHub Repository and give it a name `my-resume` +## Project Setup and Repository Creation +Let's start by setting up your project foundation. This process mirrors real-world development workflows where projects begin with proper repository initialization and structure planning. -**Step 2** Create an `index.html` file in your repository. We will add at least one file while still on github.com because you cannot open an empty repository on vscode.dev +### Step 1: Create Your GitHub Repository -Click the `creating a new file` link, type in the name `index.html` and select the `Commit new file` button +Setting up a dedicated repository ensures your project is properly organized and version-controlled from the beginning. -![Create a new file on github.com](../images/new-file-github.com.png) +1. **Navigate** to [GitHub.com](https://github.com) and sign in to your account +2. **Click** the green "New" button or the "+" icon in the top-right corner +3. **Name** your repository `my-resume` (or choose a personalized name like `john-smith-resume`) +4. **Add** a brief description: "Professional resume website built with HTML and CSS" +5. **Select** "Public" to make your resume accessible to potential employers +6. **Check** "Add a README file" to create an initial project description +7. **Click** "Create repository" to finalize setup +> πŸ’‘ **Repository Naming Tip**: Use descriptive, professional names that clearly indicate the project's purpose. This helps when sharing with employers or during portfolio reviews. -**Step 3:** Open [VSCode.dev](https://vscode.dev) and select the `Open Remote Repository` button +### Step 2: Initialize Project Structure -Copy the url to the repository you just created for your resume site and paste it in the input box: +Since VSCode.dev requires at least one file to open a repository, we'll create our main HTML file directly on GitHub before switching to the web editor. -_Replace `your-username` with your github username_ +1. **Click** "creating a new file" link in your new repository +2. **Type** `index.html` as the filename +3. **Add** this initial HTML structure: +```html + + + + + + Your Name - Professional Resume + + +

Your Name

+

Professional Resume Website

+ + ``` -https://github.com/your-username/my-resume -``` -βœ… If successful, you'll see your project and the index.html file open up on the text editor on the browser. +4. **Write** a commit message: "Add initial HTML structure" +5. **Click** "Commit new file" to save your changes + +![Creating initial file on GitHub](../images/new-file-github.com.png) + +**Here's what this initial setup accomplishes:** +- **Establishes** proper HTML5 document structure with semantic elements +- **Includes** viewport meta tag for responsive design compatibility +- **Sets** a descriptive page title that appears in browser tabs +- **Creates** the foundation for professional content organization + + +## Working in VSCode.dev + +Now that your repository foundation is established, let's transition to VSCode.dev for the main development work. This web-based editor provides all the tools needed for professional web development. + +### Step 3: Open Your Project in VSCode.dev + +1. **Navigate** to [vscode.dev](https://vscode.dev) in a new browser tab +2. **Click** "Open Remote Repository" on the welcome screen +3. **Copy** your repository URL from GitHub and paste it into the input field + + Format: `https://github.com/your-username/my-resume` + + *Replace `your-username` with your actual GitHub username* -![Create a new file](../images/project-on-vscode.dev.png) +4. **Press** Enter to load your project +βœ… **Success indicator**: You should see your project files in the Explorer sidebar and `index.html` available for editing in the main editor area. -**Step 4:** Open the `index.html` file, paste in the code below on your code area and save +![Project loaded in VSCode.dev](../images/project-on-vscode.dev.png) + +**What you'll see in the interface:** +- **Explorer sidebar**: **Displays** your repository files and folder structure +- **Editor area**: **Shows** the content of selected files for editing +- **Activity bar**: **Provides** access to features like Source Control and Extensions +- **Status bar**: **Indicates** connection status and current branch information + +### Step 4: Build Your Resume Content + +Replace the placeholder content in `index.html` with a comprehensive resume structure. This HTML provides the foundation for a professional presentation of your qualifications.
- HTML code responsible for the content on your resume website. +Complete HTML Resume Structure + +```html + + + + + + + + Your Name - Professional Resume + + + - - - - - - Your Name Goes Here! - - - -
- -
-
-

ABOUT

- -

Write a blurb about yourself!

-
-
-

WORK EXPERIENCE

- -

Job Title

-

- Organization Name Goes Here | Start Month – End Month -

-
    -
  • Task 1 - Write what you did!
  • -
  • Task 2 - Write what you did!
  • -
  • Write the outcomes/impact of your contribution
  • - -
-

Job Title 2

-

- Organization Name Goes Here | Start Month – End Month -

-
    -
  • Task 1 - Write what you did!
  • -
  • Task 2 - Write what you did!
  • -
  • Write the outcomes/impact of your contribution
  • - -
-
-
-
- - +
+ + +
+
+

ABOUT

+

Write a compelling summary that highlights your passion for web development, key achievements, and career goals. This section should give employers insight into your personality and professional approach.

+
+ +
+

WORK EXPERIENCE

+
+

Job Title

+

Company Name | Start Date – End Date

+
    +
  • Describe a key accomplishment or responsibility
  • +
  • Highlight specific skills or technologies used
  • +
  • Quantify impact where possible (e.g., "Improved efficiency by 25%")
  • +
+
+ +
+

Previous Job Title

+

Previous Company | Start Date – End Date

+
    +
  • Focus on transferable skills and achievements
  • +
  • Demonstrate growth and learning progression
  • +
  • Include any leadership or collaboration experiences
  • +
+
+
+ +
+

PROJECTS

+
+

Project Name

+

Brief description of what the project accomplishes and technologies used.

+ View Project +
+
+
+
+ + +```
-Add your resume details to replace the _placeholder text_ on the html code +**Customization guidelines:** +- **Replace** all placeholder text with your actual information +- **Adjust** sections based on your experience level and career focus +- **Add** or remove sections as needed (e.g., Certifications, Volunteer Work, Languages) +- **Include** links to your actual profiles and projects -**Step 5:** Hover on the My-Resume folder, click the `New File ...` icon and create 2 new files in your project: `style.css` and `codeswing.json` files +### Step 5: Create Supporting Files -**Step 6:** Open the `style.css` file, paste in the code below and save +Professional websites require organized file structures. Create the CSS stylesheet and configuration files needed for a complete project. -
- CSS code to format the layout of the site. - - body { - font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; - font-size: 16px; - max-width: 960px; - margin: auto; - } - h1 { - font-size: 3em; - letter-spacing: .6em; - padding-top: 1em; - padding-bottom: 1em; - } - - h2 { - font-size: 1.5em; - padding-bottom: 1em; - } - - h3 { - font-size: 1em; - padding-bottom: 1em; - } - main { - display: grid; - grid-template-columns: 40% 60%; - margin-top: 3em; - } - header { - text-align: center; - margin: auto 2em; - } - - section { - margin: auto 1em 4em 2em; - } - - i { - margin-right: .5em; - } - - p { - margin: .2em auto - } - - hr { - border: none; - background-color: lightgray; - height: 1px; - } - - h1, h2, h3 { - font-weight: 100; - margin-bottom: 0; - } - #mainLeft { - border-right: 1px solid lightgray; - } - +1. **Hover** over your project folder name in the Explorer sidebar +2. **Click** the "New File" icon (πŸ“„+) that appears +3. **Create** these files one at a time: + - `style.css` (for styling and layout) + - `codeswing.json` (for the preview extension configuration) + +**Creating the CSS file (`style.css`):** + +
+Professional CSS Styling + +```css +/* Modern Resume Styling */ +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + font-size: 16px; + line-height: 1.6; + max-width: 960px; + margin: 0 auto; + padding: 20px; + color: #333; + background-color: #f9f9f9; +} + +/* Header Styling */ +header { + text-align: center; + margin-bottom: 3em; + padding: 2em; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + border-radius: 10px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +h1 { + font-size: 3em; + letter-spacing: 0.1em; + margin-bottom: 0.2em; + font-weight: 300; +} + +.role { + font-size: 1.3em; + font-weight: 300; + margin: 1em 0; +} + +/* Main Content Layout */ +main { + display: grid; + grid-template-columns: 35% 65%; + gap: 3em; + margin-top: 3em; + background: white; + padding: 2em; + border-radius: 10px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); +} + +/* Typography */ +h2 { + font-size: 1.4em; + font-weight: 600; + margin-bottom: 1em; + color: #667eea; + border-bottom: 2px solid #667eea; + padding-bottom: 0.3em; +} + +h3 { + font-size: 1.1em; + font-weight: 600; + margin-bottom: 0.5em; + color: #444; +} + +/* Section Styling */ +section { + margin-bottom: 2.5em; +} + +#mainLeft { + border-right: 1px solid #e0e0e0; + padding-right: 2em; +} + +/* Contact Links */ +section a { + color: #667eea; + text-decoration: none; + transition: color 0.3s ease; +} + +section a:hover { + color: #764ba2; + text-decoration: underline; +} + +/* Icons */ +i { + margin-right: 0.8em; + width: 20px; + text-align: center; + color: #667eea; +} + +/* Lists */ +ul { + list-style: none; + padding-left: 0; +} + +li { + margin: 0.5em 0; + padding: 0.3em 0; + position: relative; +} + +li:before { + content: "β–Έ"; + color: #667eea; + margin-right: 0.5em; +} + +/* Work Experience */ +.job, .project { + margin-bottom: 2em; + padding-bottom: 1.5em; + border-bottom: 1px solid #f0f0f0; +} + +.company { + font-style: italic; + color: #666; + margin-bottom: 0.5em; +} + +/* Responsive Design */ +@media (max-width: 768px) { + main { + grid-template-columns: 1fr; + gap: 2em; + } + + #mainLeft { + border-right: none; + border-bottom: 1px solid #e0e0e0; + padding-right: 0; + padding-bottom: 2em; + } + + h1 { + font-size: 2.2em; + } + + body { + padding: 10px; + } +} + +/* Print Styles */ +@media print { + body { + background: white; + color: black; + font-size: 12pt; + } + + header { + background: none; + color: black; + box-shadow: none; + } + + main { + box-shadow: none; + } +} +```
-**Step 6:** Open the `codeswing.json` file, paste in the code below and save +**Creating the configuration file (`codeswing.json`):** - { +```json +{ "scripts": [], "styles": [] - } +} +``` + +**Understanding the CSS features:** +- **Uses** CSS Grid for responsive, professional layout structure +- **Implements** modern color schemes with gradient headers +- **Includes** hover effects and smooth transitions for interactivity +- **Provides** responsive design that works on all device sizes +- **Adds** print-friendly styles for PDF generation + + +### Step 6: Install and Configure Extensions + +Extensions enhance your development experience by providing live preview capabilities and improved workflow tools. The CodeSwing extension is particularly useful for web development projects. + +**Installing the CodeSwing Extension:** + +1. **Click** the Extensions icon (🧩) in the Activity Bar +2. **Search** for "CodeSwing" in the marketplace search box +3. **Select** the CodeSwing extension from the search results +4. **Click** the blue "Install" button + +![Installing the CodeSwing extension](../images/install-extension.gif) + +**What CodeSwing provides:** +- **Enables** live preview of your website as you edit +- **Displays** changes in real-time without manual refresh +- **Supports** multiple file types including HTML, CSS, and JavaScript +- **Provides** an integrated development environment experience + +**Immediate results after installation:** +Once CodeSwing is installed, you'll see a live preview of your resume website appear in the editor. This allows you to see exactly how your site looks as you make changes. + +![CodeSwing extension showing live preview](../images/after-codeswing-extension-pb.png) + +**Understanding the enhanced interface:** +- **Split view**: **Shows** your code on one side and live preview on the other +- **Real-time updates**: **Reflects** changes immediately as you type +- **Interactive preview**: **Allows** you to test links and interactions +- **Mobile simulation**: **Provides** responsive design testing capabilities + +### Step 7: Version Control and Publishing + +Now that your resume website is complete, use Git to save your work and make it available online. + +**Committing your changes:** + +1. **Click** the Source Control icon (🌿) in the Activity Bar +2. **Review** all the files you've created and modified in the "Changes" section +3. **Stage** your changes by clicking the "+" icon next to each file +4. **Write** a descriptive commit message, such as: + - "Add complete resume website with responsive design" + - "Implement professional styling and content structure" +5. **Click** the checkmark (βœ“) to commit and push your changes + +**Effective commit message examples:** +- "Add professional resume content and styling" +- "Implement responsive design for mobile compatibility" +- "Update contact information and project links" + +> πŸ’‘ **Professional Tip**: Good commit messages help track your project's evolution and demonstrate attention to detail – qualities that employers value. +**Accessing your published site:** +Once committed, you can return to your GitHub repository using the hamburger menu (☰) in the top-left corner. Your resume website is now version-controlled and ready for deployment or sharing. -**Step 7:** Install the `Codeswing extension` to visualize the resume website on the code area. +## Results and Next Steps -Click the _`Extensions`_ icon on the activity bar and type in Codeswing. Either click the _blue install button_ on the expanded activity bar to install or use the install button that appears on the code area once you select the extension to load additional information. Immediately after installing the extension, observe your code area to see the changes to your project πŸ˜ƒ +**Congratulations! πŸŽ‰** You've successfully created a professional resume website using VSCode.dev. Your project demonstrates: +**Technical skills demonstrated:** +- **Repository management**: Created and organized a complete project structure +- **Web development**: Built a responsive website using modern HTML5 and CSS3 +- **Version control**: Implemented proper Git workflow with meaningful commits +- **Tool proficiency**: Effectively used VSCode.dev's interface and extension system -![Install extensions](../images/install-extension.gif) +**Professional outcomes achieved:** +- **Online presence**: A shareable URL that showcases your qualifications +- **Modern format**: An interactive alternative to traditional PDF resumes +- **Demonstrable skills**: Concrete evidence of your web development capabilities +- **Easy updates**: A foundation you can continuously improve and customize -This is what you will see on your on your screen after you install the extension. +### Deployment Options -![Codeswing extension in action](../images/after-codeswing-extension-pb.png) +To make your resume accessible to employers, consider these hosting options: -If you are satisfied with the changes you made, hover on the `Changes` folder and click the `+` button to stage the changes. +**GitHub Pages (Recommended):** +1. Go to your repository Settings on GitHub +2. Scroll to the "Pages" section +3. Select "Deploy from a branch" and choose "main" +4. Your site will be available at `https://your-username.github.io/my-resume` -Type in a commit message _(A description of the change you have made to the project)_ and commit your changes by clicking the `check`.Once done working on your project, select the hamburger menu icon at the top left to return to the repository on GitHub. +**Alternative platforms:** +- **Netlify**: Automatic deployment with custom domains +- **Vercel**: Fast deployment with modern hosting features +- **GitHub Codespaces**: Development environment with built-in preview -Congratulations πŸŽ‰ You have just created your resume website using vscode.dev in few steps. -## πŸš€ Challenge +### Enhancement Suggestions -Open a remote repository you have permissions to make changes and update some files. Next, try creating a new branch with your changes and make a Pull Request. +Continue developing your skills by adding these features: - +**Technical improvements:** +- **JavaScript interactivity**: Add smooth scrolling or interactive elements +- **Dark mode toggle**: Implement theme switching for user preference +- **Contact form**: Enable direct communication from potential employers +- **SEO optimization**: Add meta tags and structured data for better search visibility + +**Content enhancements:** +- **Project portfolio**: Link to GitHub repositories and live demonstrations +- **Skills visualization**: Create progress bars or skill rating systems +- **Testimonials section**: Include recommendations from colleagues or instructors +- **Blog integration**: Add a blog section to showcase your learning journey + +## GitHub Copilot Agent Challenge πŸš€ + +Use the Agent mode to complete the following challenge: + +**Description:** Enhance your resume website with advanced features that demonstrate professional web development capabilities and modern design principles. + +**Prompt:** Building on your existing resume website, implement these advanced features: +1. Add a dark/light theme toggle with smooth transitions +2. Create an interactive skills section with animated progress bars +3. Implement a contact form with form validation +4. Add a projects portfolio section with hover effects and modal popups +5. Include a blog section with at least 3 sample posts about your learning journey +6. Optimize for SEO with proper meta tags, structured data, and performance +7. Deploy the enhanced site using GitHub Pages or Netlify +8. Document all new features in your README.md with screenshots + +Your enhanced website should demonstrate mastery of modern web development practices including responsive design, JavaScript interactivity, and professional deployment workflows. + +## Challenge Extension + +Ready to take your skills further? Try these advanced challenges: + +**πŸ“± Mobile-First Redesign:** Completely rebuild your site using a mobile-first approach with CSS Grid and Flexbox + +**πŸ” SEO Optimization:** Implement comprehensive SEO including meta tags, structured data, and performance optimization + +**🌐 Multi-language Support:** Add internationalization features to support multiple languages + +**πŸ“Š Analytics Integration:** Add Google Analytics to track visitor engagement and optimize your content + +**πŸš€ Performance Optimization:** Achieve perfect Lighthouse scores across all categories ## Review & Self Study -Read more about [VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) and some of its other features. +Expand your knowledge with these resources: + +**Advanced VSCode.dev Features:** +- [VSCode.dev Documentation](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) - Complete guide to web-based editing +- [GitHub Codespaces](https://docs.github.com/en/codespaces) - Cloud development environments + +**Web Development Best Practices:** +- **Responsive Design**: Study CSS Grid and Flexbox for modern layouts +- **Accessibility**: Learn WCAG guidelines for inclusive web design +- **Performance**: Explore tools like Lighthouse for optimization +- **SEO**: Understand search engine optimization fundamentals + +**Professional Development:** +- **Portfolio Building**: Create additional projects to showcase diverse skills +- **Open Source**: Contribute to existing projects to gain collaboration experience +- **Networking**: Share your resume website in developer communities for feedback +- **Continuous Learning**: Stay updated with web development trends and technologies + +--- + +**Your Next Steps:** Share your resume website with friends, family, or mentors for feedback. Use their suggestions to iterate and improve your design. Remember, this project is not just a resume – it's a demonstration of your growth as a web developer! diff --git a/9-chat-project/README.md b/9-chat-project/README.md index 55e16660..a66cedfd 100644 --- a/9-chat-project/README.md +++ b/9-chat-project/README.md @@ -1,26 +1,83 @@ -# Chat project +# Build a Chat Assistant with AI -This chat project shows how to build a Chat Assistant using GitHub Models. +Imagine having a conversation with a computer that feels almost human – one that understands context, provides thoughtful responses, and can help you solve problems creatively. This isn't science fiction anymore; it's the reality of modern AI-powered applications that you can build today! In this comprehensive lesson, you'll discover how to create a fully functional chat assistant that demonstrates the incredible capabilities of artificial intelligence while using the web development skills you already know. -Here's what the finished project looks like: +Think of AI as having a brilliant conversation partner who has read virtually everything on the internet and can instantly recall and synthesize that information to help you. Just like how you might ask a knowledgeable friend for advice, you can ask an AI questions, and it will provide thoughtful, contextual responses. The magic happens when you combine this AI capability with the web technologies you're familiar with – HTML for structure, CSS for styling, JavaScript for interactivity, and backend APIs for data processing. -![Chat app](./assets/screenshot.png) +Building chat assistants is like creating a bridge between human communication and machine intelligence. You'll learn not just the technical "how" of connecting to AI services, but also the "why" behind design decisions that make AI feel natural and helpful. This project will demystify artificial intelligence, showing you that it's not mysterious magic, but rather a powerful tool that you can integrate into web applications using familiar programming patterns. By the end of this lesson, you'll understand how companies like ChatGPT, Claude, and Google's Bard work under the hood, and you'll have built your own version from scratch! -Some context, building Chat assistants using generative AI is a great way to start learning about AI. What you'll learn is to integrate generative AI into a web app throughout this lesson, let's begin. +Here's what your finished project will look like: -## Connecting to generative AI +![Chat app interface showing conversation between user and AI assistant](./assets/screenshot.png) -For the backend, we're using GitHub Models. It's a great service that enables you to use AI for free. Go to its playground and grab code that corresponds to your chosen backend language. Here's what it looks like at [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground) +## Understanding AI: From Mystery to Mastery -![GitHub Models AI Playground](./assets/playground.png) +Before we dive into code, let's demystify what artificial intelligence actually is and how it works. If you're a web developer, you're already familiar with APIs – you send a request with some data, and you get back a response. AI APIs work similarly, but instead of retrieving stored data from a database, they generate new, contextual responses based on patterns learned from vast amounts of text. -As we said, select the "Code" tab and your chosen runtime. +### What is "Generative AI" Really? -![Playground choice](./assets/playground-choice.png) +Think of generative AI like an incredibly well-read librarian who has memorized millions of books, articles, and conversations. When you ask this librarian a question, they don't just look up a pre-written answer – they synthesize information from everything they've learned to create a new, original response tailored to your specific question. -### Using Python +**Here's a simple analogy:** +- **Traditional database**: Like a filing cabinet where you ask for "file A" and always get the exact same document +- **Search engine**: Like a smart filing system that finds relevant documents based on keywords +- **Generative AI**: Like a creative research assistant who reads all the documents and writes you a custom report based on your specific needs -In this case we select Python, which will mean we pick this code: +```mermaid +graph LR + A[Your Question] --> B[AI Model] + B --> C[Pattern Recognition] + C --> D[Content Generation] + D --> E[Contextual Response] + + F[Training Data
Books, Articles, Web] --> B +``` + +### How AI Models Learn (The Simple Version) + +AI models like GPT-4 are trained on enormous amounts of text – think of it as reading billions of web pages, books, articles, and conversations. During training, the AI learns patterns: +- How sentences are structured +- What words commonly appear together +- How to maintain context in conversations +- How to respond appropriately to different types of questions + +**A real-world comparison**: It's like learning a language by listening to millions of conversations. Eventually, you start to understand not just individual words, but the subtle patterns of how people communicate, the context that makes responses appropriate, and even cultural nuances. + +### Why GitHub Models? + +We'll use GitHub Models because it provides free access to enterprise-grade AI capabilities without the complexity of managing your own AI infrastructure. Think of it as "AI-as-a-Service" – just like how you might use a weather API instead of building your own weather prediction system. + +```mermaid +graph LR + A[Frontend Chat UI] --> B[Your Backend API] + B --> C[GitHub Models API] + C --> D[AI Model Processing] + D --> C + C --> B + B --> A +``` + +For the backend integration, we're using GitHub Models because it provides enterprise-grade AI capabilities with a developer-friendly interface. Navigate to the [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground) to explore the available models and get familiar with the interface. + +![GitHub Models AI Playground interface with model selection and testing area](./assets/playground.png) + +**Understanding the playground interface:** +- **Explores** different AI models like GPT-4o-mini, Claude, and others available for free +- **Tests** your prompts and system messages before implementing them in code +- **Generates** ready-to-use code snippets for your preferred programming language +- **Adjusts** parameters like temperature and max tokens to fine-tune AI responses + +Once you're familiar with the playground, select the "Code" tab and choose your preferred runtime to get the implementation code. + +![Playground choice showing code generation options for different programming languages](./assets/playground-choice.png) + +## Setting Up the Python Backend Integration + +Now let's implement the AI integration using Python. Python is excellent for AI applications because of its simple syntax and powerful libraries. We'll start with the code from GitHub Models playground and then refactor it into a reusable, production-ready function. + +### Understanding the Base Implementation + +When you select Python in the playground, you'll get code similar to this. Let's examine it step by step: ```python """Run this model in Python @@ -37,6 +94,7 @@ client = OpenAI( api_key=os.environ["GITHUB_TOKEN"], ) +```python response = client.chat.completions.create( messages=[ { @@ -57,282 +115,1731 @@ response = client.chat.completions.create( print(response.choices[0].message.content) ``` -Let's clean up this code a bit so it's reusable: +**Understanding the AI conversation structure:** +- **Imports** the necessary libraries for AI integration (`os` for environment variables, `OpenAI` for API access) +- **Configures** the OpenAI client to point to GitHub Models' inference endpoint +- **Authenticates** using a GitHub Personal Access Token stored as an environment variable +- **Structures** the conversation with system and user message roles (more on this below!) +- **Sends** the request to the AI model with specific parameters for response generation +- **Extracts** and prints the AI's response from the returned data structure + +### Understanding Message Roles: The AI Conversation Framework + +AI conversations use a specific structure with different "roles" that serve distinct purposes: ```python -def call_llm(prompt: str, system_message: str): - response = client.chat.completions.create( - messages=[ - { - "role": "system", - "content": system_message, - }, - { - "role": "user", - "content": prompt, - } - ], - model="openai/gpt-4o-mini", - temperature=1, - max_tokens=4096, - top_p=1 - ) +messages=[ + { + "role": "system", + "content": "You are a helpful assistant who explains things simply." + }, + { + "role": "user", + "content": "What is machine learning?" + } +] +``` + +**Think of it like directing a play:** +- **System role**: Like stage directions for an actor – it tells the AI how to behave, what personality to have, and how to respond +- **User role**: The actual question or message from the person using your application +- **Assistant role**: The AI's response (you don't send this, but it appears in conversation history) + +**Real-world analogy**: Imagine you're introducing a friend to someone at a party: +- **System message**: "This is my friend Sarah, she's a doctor who's great at explaining medical concepts in simple terms" +- **User message**: "Can you explain how vaccines work?" +- **Assistant response**: Sarah responds as a friendly doctor, not as a lawyer or a chef + +### Demystifying AI Parameters: Fine-Tuning Your AI's Personality + +Those mysterious parameters in the API call aren't just random numbers – they're powerful tools that control how your AI behaves. Let's break them down with practical examples: + +#### Temperature (0.0 to 2.0): The Creativity Dial + +**What it does**: Controls how "creative" or "random" the AI's responses are. + +**Think of it like ordering at a restaurant:** +- **Temperature = 0.1**: "I'll have the usual" (very predictable, same response every time) +- **Temperature = 0.7**: "I'll try something new, but not too crazy" (balanced creativity) +- **Temperature = 1.5**: "Surprise me with something completely unexpected!" (very creative, unpredictable) + +```python +# Very predictable responses (good for factual questions) +response = client.chat.completions.create( + messages=[{"role": "user", "content": "What is 2+2?"}], + temperature=0.1 # Will almost always say "4" +) + +# Creative responses (good for brainstorming) +response = client.chat.completions.create( + messages=[{"role": "user", "content": "Write a creative story opening"}], + temperature=1.2 # Will generate unique, unexpected stories +) +``` + +#### Max Tokens (1 to 4096+): The Response Length Controller + +**What it does**: Limits how long the AI's response can be. + +**Think of tokens like words** (roughly 1 token = 0.75 words in English): +- **max_tokens=50**: Short responses (like a tweet) +- **max_tokens=500**: Medium responses (like a paragraph) +- **max_tokens=2000**: Long responses (like a detailed explanation) + +```python +# Short, concise answers +response = client.chat.completions.create( + messages=[{"role": "user", "content": "Explain JavaScript"}], + max_tokens=100 # Forces a brief explanation +) + +# Detailed, comprehensive answers +response = client.chat.completions.create( + messages=[{"role": "user", "content": "Explain JavaScript"}], + max_tokens=1500 # Allows for detailed explanations with examples +) +``` + +#### Top_p (0.0 to 1.0): The Focus Parameter - return response.choices[0].message.content +**What it does**: Controls how focused the AI is on the most likely responses. + +**Imagine the AI has a vocabulary of responses ranked by likelihood:** +- **top_p=0.1**: Only considers the top 10% most likely words (very focused) +- **top_p=0.9**: Considers 90% of possible words (more diverse) +- **top_p=1.0**: Considers all possible words (maximum diversity) + +**Practical example**: If you ask "The sky is usually..." +- **Low top_p**: Almost certainly responds "blue" +- **High top_p**: Might respond "blue", "cloudy", "vast", "changing", etc. + +### Putting It All Together: Parameter Combinations for Different Use Cases + +```python +# For factual, consistent answers (like a documentation bot) +factual_params = { + "temperature": 0.2, + "max_tokens": 300, + "top_p": 0.3 +} + +# For creative writing assistance +creative_params = { + "temperature": 1.1, + "max_tokens": 1000, + "top_p": 0.9 +} + +# For conversational, helpful responses (balanced) +conversational_params = { + "temperature": 0.7, + "max_tokens": 500, + "top_p": 0.8 +} ``` -With this function `call_llm` we can now take a prompt and a system prompt and the function ends up returning the result. +**Understanding why these parameters matter**: Different applications need different types of responses. A customer service bot should be consistent and factual (low temperature), while a creative writing assistant should be imaginative and varied (high temperature). Understanding these parameters gives you control over your AI's personality and response style. +``` + +**Breaking down what happens here:** +- **Imports** the necessary libraries for AI integration (`os` for environment variables, `OpenAI` for API access) +- **Configures** the OpenAI client to point to GitHub Models' inference endpoint +- **Authenticates** using a GitHub Personal Access Token stored as an environment variable +- **Structures** the conversation with system and user message roles +- **Sends** the request to the AI model with specific parameters for response generation +- **Extracts** and prints the AI's response from the returned data structure + +> πŸ” **Security Note**: Never hardcode API keys in your source code! Always use environment variables to store sensitive credentials like your `GITHUB_TOKEN`. + +### Creating a Reusable AI Function + +Let's refactor this code into a clean, reusable function that we can easily integrate into our web application: + +```python +import asyncio +from openai import AsyncOpenAI + +# Use AsyncOpenAI for better performance +client = AsyncOpenAI( + base_url="https://models.github.ai/inference", + api_key=os.environ["GITHUB_TOKEN"], +) + +async def call_llm_async(prompt: str, system_message: str = "You are a helpful assistant."): + """ + Sends a prompt to the AI model asynchronously and returns the response. + + Args: + prompt: The user's question or message + system_message: Instructions that define the AI's behavior and personality + + Returns: + str: The AI's response to the prompt + """ + try: + response = await client.chat.completions.create( + messages=[ + { + "role": "system", + "content": system_message, + }, + { + "role": "user", + "content": prompt, + } + ], + model="openai/gpt-4o-mini", + temperature=1, + max_tokens=4096, + top_p=1 + ) + return response.choices[0].message.content + except Exception as e: + logger.error(f"AI API error: {str(e)}") + return "I'm sorry, I'm having trouble processing your request right now." + +# Backward compatibility function for synchronous calls +def call_llm(prompt: str, system_message: str = "You are a helpful assistant."): + """Synchronous wrapper for async AI calls.""" + return asyncio.run(call_llm_async(prompt, system_message)) +``` + +**Understanding this improved function:** +- **Accepts** two parameters: the user's prompt and an optional system message +- **Provides** a default system message for general assistant behavior +- **Uses** proper Python type hints for better code documentation +- **Includes** a detailed docstring explaining the function's purpose and parameters +- **Returns** only the response content, making it easy to use in our web API +- **Maintains** the same model parameters for consistent AI behavior + +### The Magic of System Prompts: Programming AI Personality -### Customize AI Assistant +If parameters control how the AI thinks, system prompts control who the AI thinks it is. This is where the real magic happens – you're essentially giving the AI a role to play, complete with personality, expertise, and communication style. -If you want to customize the AI assistant you can specify how you want it to behave by populating the system prompt like so: +**Think of system prompts like hiring different experts**: Instead of having one generic assistant, you can create specialized experts for different tasks, each with their own knowledge base and communication style. + +#### Understanding System Prompt Psychology + +**Why system prompts work**: AI models are trained on countless conversations and texts where people adopt different roles and expertise levels. When you give the AI a specific role, it activates the patterns it learned from similar contexts. + +**Real-world analogy**: It's like method acting. When an actor is told "you're a wise old professor," they automatically adjust their posture, vocabulary, and mannerisms. AI does something similar with language patterns. + +#### Crafting Effective System Prompts: The Art and Science + +**The anatomy of a great system prompt:** +1. **Role/Identity**: Who is the AI? +2. **Expertise**: What do they know? +3. **Communication style**: How do they speak? +4. **Specific instructions**: What should they focus on? ```python -call_llm("Tell me about you", "You're Albert Einstein, you only know of things in the time you were alive") +# ❌ Vague system prompt +"You are helpful." + +# βœ… Detailed, effective system prompt +"You are Dr. Sarah Chen, a senior software engineer with 15 years of experience at major tech companies. You explain programming concepts using real-world analogies and always provide practical examples. You're patient with beginners and enthusiastic about helping them understand complex topics." ``` -## Expose it via a Web API +#### System Prompt Examples with Context -Great, we have an AI part done, let's see how we can integrate that into a Web API. For the Web API, we're choosing to use Flask, but any web framework should be good. Let's see the code for it: +Let's see how different system prompts create completely different AI personalities: -### Using Python +```python +# Example 1: The Patient Teacher +teacher_prompt = """ +You are an experienced programming instructor who has taught thousands of students. +You break down complex concepts into simple steps, use analogies from everyday life, +and always check if the student understands before moving on. You're encouraging +and never make students feel bad for not knowing something. +""" + +# Example 2: The Creative Collaborator +creative_prompt = """ +You are a creative writing partner who loves brainstorming wild ideas. You're +enthusiastic, imaginative, and always build on the user's ideas rather than +replacing them. You ask thought-provoking questions to spark creativity and +offer unexpected perspectives that make stories more interesting. +""" + +# Example 3: The Strategic Business Advisor +business_prompt = """ +You are a strategic business consultant with an MBA and 20 years of experience +helping startups scale. You think in frameworks, provide structured advice, +and always consider both short-term tactics and long-term strategy. You ask +probing questions to understand the full business context before giving advice. +""" +``` + +#### Seeing System Prompts in Action + +Let's test the same question with different system prompts to see the dramatic differences: + +**Question**: "How do I handle user authentication in my web app?" + +```python +# With teacher prompt: +teacher_response = call_llm( + "How do I handle user authentication in my web app?", + teacher_prompt +) +# Typical response: "Great question! Let's break authentication down into simple steps. +# Think of it like a nightclub bouncer checking IDs..." + +# With business prompt: +business_response = call_llm( + "How do I handle user authentication in my web app?", + business_prompt +) +# Typical response: "From a strategic perspective, authentication is crucial for user +# trust and regulatory compliance. Let me outline a framework considering security, +# user experience, and scalability..." +``` + +#### Advanced System Prompt Techniques + +**1. Context Setting**: Give the AI background information +```python +system_prompt = """ +You are helping a junior developer who just started their first job at a startup. +They know basic HTML/CSS/JavaScript but are new to backend development and databases. +Be encouraging and explain things step-by-step without being condescending. +""" +``` + +**2. Output Formatting**: Tell the AI how to structure responses +```python +system_prompt = """ +You are a technical mentor. Always structure your responses as: +1. Quick Answer (1-2 sentences) +2. Detailed Explanation +3. Code Example +4. Common Pitfalls to Avoid +5. Next Steps for Learning +""" +``` + +**3. Constraint Setting**: Define what the AI should NOT do +```python +system_prompt = """ +You are a coding tutor focused on teaching best practices. Never write complete +solutions for the user - instead, guide them with hints and questions so they +learn by doing. Always explain the 'why' behind coding decisions. +""" +``` + +#### Why This Matters for Your Chat Assistant + +Understanding system prompts gives you incredible power to create specialized AI assistants: +- **Customer service bot**: Helpful, patient, policy-aware +- **Learning tutor**: Encouraging, step-by-step, checks understanding +- **Creative partner**: Imaginative, builds on ideas, asks "what if?" +- **Technical expert**: Precise, detailed, security-conscious + +**The key insight**: You're not just calling an AI API – you're creating a custom AI personality that serves your specific use case. This is what makes modern AI applications feel tailored and useful rather than generic. + +## Building the Web API with FastAPI: Your High-Performance AI Communication Hub + +Now that we understand how AI works, let's create the bridge between your frontend and the AI service. We'll use FastAPI, a modern, high-performance web framework that's specifically designed for building APIs with excellent support for async operations – making it perfect for AI applications that need to handle multiple concurrent requests efficiently. Think of your FastAPI server as a translator and coordinator that receives requests from your frontend, processes them asynchronously, and communicates with AI services without blocking other requests. + +### Why FastAPI for AI Applications? + +You might wonder: "Why can't I just call the AI directly from my frontend JavaScript?" And "Why FastAPI instead of other frameworks?" Great questions! Here's why we need this intermediary layer and why FastAPI is ideal: + +**Why FastAPI excels for AI applications:** +- **Async by default**: Can handle multiple AI requests simultaneously without blocking +- **Automatic documentation**: Generates interactive API docs at `/docs` endpoint +- **Type safety**: Built-in data validation prevents errors before they reach your AI +- **Performance**: One of the fastest Python frameworks, crucial for real-time chat +- **Modern Python**: Uses Python 3.6+ features like type hints and async/await + +**Why we need a backend API:** + +**Security**: Your AI API key is like a password – if you put it in frontend JavaScript, anyone who views your website's source code could steal it and use your AI credits. The backend keeps sensitive credentials secure. + +**Rate Limiting & Control**: The backend lets you control how often users can make requests, implement user authentication, and add logging to track usage. + +**Data Processing**: You might want to save conversations, filter inappropriate content, or combine multiple AI services. The backend is where this logic lives. + +**Think of it like a restaurant:** +- **Frontend**: The dining room where customers sit +- **Backend API**: The waiter who takes orders and brings food +- **AI Service**: The kitchen that prepares the meal +- **Database**: The pantry where ingredients (data) are stored + +### Understanding the Request-Response Flow + +Let's trace what happens when a user sends a message: + +```mermaid +sequenceDiagram + participant User as πŸ‘€ User + participant Frontend as 🌐 Frontend + participant API as πŸ”§ FastAPI Server + participant AI as πŸ€– AI Service + + User->>Frontend: Types "Hello AI!" + Frontend->>API: POST /hello {"message": "Hello AI!"} + Note over API: Validates request
Adds system prompt + API->>AI: Sends formatted request + AI->>API: Returns AI response + Note over API: Processes response
Logs conversation + API->>Frontend: {"response": "Hello! How can I help?"} + Frontend->>User: Displays AI message +``` + +**Understanding each step:** +1. **User interaction**: Person types in the chat interface +2. **Frontend processing**: JavaScript captures the input and formats it as JSON +3. **API validation**: FastAPI automatically validates the request using Pydantic models +4. **AI integration**: Backend adds context (system prompt) and calls the AI service +5. **Response handling**: API receives AI response and can modify it if needed +6. **Frontend display**: JavaScript shows the response in the chat interface + +### Understanding API Architecture + +```mermaid +sequenceDiagram + participant Frontend + participant FastAPI + participant AI Function + participant GitHub Models + + Frontend->>FastAPI: POST /hello {"message": "Hello AI!"} + FastAPI->>AI Function: call_llm(message, system_prompt) + AI Function->>GitHub Models: API request + GitHub Models->>AI Function: AI response + AI Function->>FastAPI: response text + FastAPI->>Frontend: {"response": "Hello! How can I help?"} +``` + +### Creating the FastAPI Application + +Let's build our API step by step. Create a file called `api.py` with the following FastAPI code: ```python # api.py -from flask import Flask, request, jsonify +from fastapi import FastAPI, HTTPException +from fastapi.middleware.cors import CORSMiddleware +from pydantic import BaseModel from llm import call_llm -from flask_cors import CORS +import logging -app = Flask(__name__) -CORS(app) # * example.com +# Configure logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) -@app.route("/", methods=["GET"]) -def index(): - return "Welcome to this API. Call POST /hello with 'message': 'my message' as JSON payload" +# Create FastAPI application +app = FastAPI( + title="AI Chat API", + description="A high-performance API for AI-powered chat applications", + version="1.0.0" +) + +# Configure CORS +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], # Configure appropriately for production + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# Pydantic models for request/response validation +class ChatMessage(BaseModel): + message: str + +class ChatResponse(BaseModel): + response: str + +@app.get("/") +async def root(): + """Root endpoint providing API information.""" + return { + "message": "Welcome to the AI Chat API", + "docs": "/docs", + "health": "/health" + } + +@app.get("/health") +async def health_check(): + """Health check endpoint.""" + return {"status": "healthy", "service": "ai-chat-api"} + +@app.post("/hello", response_model=ChatResponse) +async def chat_endpoint(chat_message: ChatMessage): + """Main chat endpoint that processes messages and returns AI responses.""" + try: + # Extract and validate message + message = chat_message.message.strip() + if not message: + raise HTTPException(status_code=400, detail="Message cannot be empty") + + logger.info(f"Processing message: {message[:50]}...") + + # Call AI service (note: call_llm should be made async for better performance) + ai_response = await call_llm_async(message, "You are a helpful and friendly assistant.") + + logger.info("AI response generated successfully") + return ChatResponse(response=ai_response) + + except HTTPException: + raise + except Exception as e: + logger.error(f"Error processing chat message: {str(e)}") + raise HTTPException(status_code=500, detail="Internal server error") + +if __name__ == "__main__": + import uvicorn + uvicorn.run(app, host="0.0.0.0", port=5000, reload=True) +``` +**Understanding the FastAPI implementation:** +- **Imports** FastAPI for modern web framework functionality and Pydantic for data validation +- **Creates** automatic API documentation (available at `/docs` when server runs) +- **Enables** CORS middleware to allow frontend requests from different origins +- **Defines** Pydantic models for automatic request/response validation and documentation +- **Uses** async endpoints for better performance with concurrent requests +- **Implements** proper HTTP status codes and error handling with HTTPException +- **Includes** structured logging for monitoring and debugging +- **Provides** health check endpoint for monitoring service status + +**Key FastAPI advantages over traditional frameworks:** +- **Automatic validation**: Pydantic models ensure data integrity before processing +- **Interactive docs**: Visit `/docs` for auto-generated, testable API documentation +- **Type safety**: Python type hints prevent runtime errors and improve code quality +- **Async support**: Handle multiple AI requests simultaneously without blocking +- **Performance**: Significantly faster request processing for real-time applications + +### Understanding CORS: The Web's Security Guard + +CORS (Cross-Origin Resource Sharing) is like a security guard at a building who checks if visitors are allowed to enter. Let's understand why this matters and how it affects your application. + +#### What is CORS and Why Does It Exist? + +**The Problem**: Imagine if any website could make requests to your bank's website on your behalf without your permission. That would be a security nightmare! Browsers prevent this by default through the "Same-Origin Policy." + +**Same-Origin Policy**: Browsers only allow web pages to make requests to the same domain, port, and protocol they were loaded from. + +**Real-world analogy**: It's like apartment building security – only residents (same origin) can access the building by default. If you want to let a friend (different origin) visit, you need to explicitly tell security it's okay. + +#### CORS in Your Development Environment + +During development, your frontend and backend run on different ports: +- Frontend: `http://localhost:3000` (or file:// if opening HTML directly) +- Backend: `http://localhost:5000` + +These are considered "different origins" even though they're on the same computer! + +```python +from fastapi.middleware.cors import CORSMiddleware + +app = FastAPI(__name__) +CORS(app) # This tells browsers: "It's okay for other origins to make requests to this API" +``` + +**What CORS configuration does in practice:** +- **Adds** special HTTP headers to API responses that tell browsers "this cross-origin request is allowed" +- **Handles** "preflight" requests (browsers sometimes check permissions before sending the actual request) +- **Prevents** the dreaded "blocked by CORS policy" error in your browser console + +#### CORS Security: Development vs Production + +```python +# 🚨 Development: Allows ALL origins (convenient but insecure) +CORS(app) + +# βœ… Production: Only allow your specific frontend domain +CORS(app, origins=["https://yourdomain.com", "https://www.yourdomain.com"]) + +# πŸ”’ Advanced: Different origins for different environments +if app.debug: # Development mode + CORS(app, origins=["http://localhost:3000", "http://127.0.0.1:3000"]) +else: # Production mode + CORS(app, origins=["https://yourdomain.com"]) +``` + +**Why this matters**: In development, `CORS(app)` is like leaving your front door unlocked – convenient but not secure. In production, you want to specify exactly which websites can talk to your API. + +#### Common CORS Scenarios and Solutions + +| Scenario | Problem | Solution | +|----------|---------|----------| +| **Local Development** | Frontend can't reach backend | Add CORSMiddleware to FastAPI | +| **GitHub Pages + Heroku** | Deployed frontend can't reach API | Add your GitHub Pages URL to CORS origins | +| **Custom Domain** | CORS errors in production | Update CORS origins to match your domain | +| **Mobile App** | App can't reach web API | Add your app's domain or use `*` carefully | + +**Pro tip**: You can check CORS headers in your browser's Developer Tools under the Network tab. Look for headers like `Access-Control-Allow-Origin` in the response. + +### Error Handling and Validation + +Notice how our API includes proper error handling: + +```python +# Validate that we received a message +if not message: + return jsonify({"error": "Message field is required"}), 400 +``` + +**Key validation principles:** +- **Checks** for required fields before processing requests +- **Returns** meaningful error messages in JSON format +- **Uses** appropriate HTTP status codes (400 for bad requests) +- **Provides** clear feedback to help frontend developers debug issues + +## Setting Up and Running Your Backend + +Now that we have our AI integration and FastAPI server ready, let's get everything running. The setup process involves installing Python dependencies, configuring environment variables, and starting your development server. + +### Python Environment Setup + +Setting up a proper Python environment is crucial for managing dependencies and avoiding conflicts with other projects. We'll use Python's built-in virtual environment feature to create an isolated space for our project. + +```bash +# Navigate to your backend directory +cd backend + +# Create a virtual environment +python -m venv venv + +# Activate the virtual environment (Linux/Mac) +source ./venv/bin/activate + +# On Windows, use: +# venv\Scripts\activate + +# Install required dependencies +pip install openai fastapi uvicorn python-dotenv +``` + +**Understanding the setup process:** +- **Creates** an isolated Python environment to prevent dependency conflicts +- **Activates** the virtual environment so all packages install locally to this project +- **Installs** the core dependencies: OpenAI for AI integration, FastAPI for high-performance web API, Uvicorn as the ASGI server +- **Includes** python-dotenv for secure environment variable management + +**Key dependencies explained:** +- **FastAPI**: Modern, fast web framework with automatic API documentation +- **Uvicorn**: Lightning-fast ASGI server that runs FastAPI applications +- **OpenAI**: Official library for GitHub Models and OpenAI API integration +- **python-dotenv**: Secure environment variable loading from .env files + +### Environment Configuration: Keeping Secrets Safe + +Before starting your API, you need to understand one of the most important concepts in web development: environment variables. This is how professional developers keep sensitive information secure while still making it accessible to their applications. + +#### What Are Environment Variables? + +**Think of environment variables like a secure lockbox** that only your application can access. Instead of writing secrets directly in your code (where anyone can see them), you store them in the environment where your code runs. + +**Real-world analogy**: It's like the difference between: +- **Bad**: Writing your house key code on a sticky note attached to your front door +- **Good**: Memorizing the code and only sharing it with trusted family members + +#### Why Environment Variables Matter + +```python +# 🚨 NEVER DO THIS - API key visible to everyone +client = OpenAI( + api_key="ghp_1234567890abcdef...", # Anyone can steal this! + base_url="https://models.github.ai/inference" +) + +# βœ… DO THIS - API key stored securely +client = OpenAI( + api_key=os.environ["GITHUB_TOKEN"], # Only your app can access this + base_url="https://models.github.ai/inference" +) +``` + +**What happens when you hardcode secrets:** +1. **Version control exposure**: Anyone with access to your Git repository sees your API key +2. **Public repositories**: If you push to GitHub, your key is visible to the entire internet +3. **Team sharing**: Other developers working on your project get access to your personal API key +4. **Security breaches**: If someone steals your API key, they can use your AI credits + +#### Setting Up Your Environment File + +Create a `.env` file in your backend directory. This file stores your secrets locally: + +```bash +# .env file - This should NEVER be committed to Git +GITHUB_TOKEN=your_github_personal_access_token_here +FASTAPI_DEBUG=True +ENVIRONMENT=development +``` + +**Understanding the .env file:** +- **One secret per line** in `KEY=value` format +- **No spaces** around the equals sign +- **No quotes** needed around values (usually) +- **Comments** start with `#` + +#### Creating Your GitHub Personal Access Token + +Your GitHub token is like a special password that gives your application permission to use GitHub's AI services: + +**Step-by-step token creation:** +1. **Go to GitHub Settings** β†’ Developer settings β†’ Personal access tokens β†’ Tokens (classic) +2. **Click "Generate new token (classic)"** +3. **Set expiration** (30 days for testing, longer for production) +4. **Select scopes**: Check "repo" and any other permissions you need +5. **Generate token** and copy it immediately (you can't see it again!) +6. **Paste into your .env file** + +```bash +# Example of what your token looks like (this is fake!) +GITHUB_TOKEN=ghp_1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R +``` + +#### Loading Environment Variables in Python + +```python +import os +from dotenv import load_dotenv + +# Load environment variables from .env file +load_dotenv() + +# Now you can access them securely +api_key = os.environ.get("GITHUB_TOKEN") +if not api_key: + raise ValueError("GITHUB_TOKEN not found in environment variables!") + +client = OpenAI( + api_key=api_key, + base_url="https://models.github.ai/inference" +) +``` + +**What this code does:** +- **Loads** your .env file and makes variables available to Python +- **Checks** if the required token exists (good error handling!) +- **Raises** a clear error if the token is missing +- **Uses** the token securely without exposing it in code + +#### Git Security: The .gitignore File + +Your `.gitignore` file tells Git which files to never track or upload: + +```bash +# .gitignore - Add these lines +.env +*.env +.env.local +.env.production +__pycache__/ +venv/ +.vscode/ +``` + +**Why this is crucial**: Once you add `.env` to `.gitignore`, Git will ignore your environment file, preventing you from accidentally uploading your secrets to GitHub. + +#### Different Environments, Different Secrets + +Professional applications use different API keys for different environments: + +```bash +# .env.development +GITHUB_TOKEN=your_development_token +DEBUG=True + +# .env.production +GITHUB_TOKEN=your_production_token +DEBUG=False +``` + +**Why this matters**: You don't want your development experiments to affect your production AI usage quota, and you want different security levels for different environments. + +### Starting Your Development Server: Bringing Your FastAPI to Life + +Now comes the exciting moment – starting your FastAPI development server and seeing your AI integration come alive! FastAPI uses Uvicorn, a lightning-fast ASGI server that's specifically designed for async Python applications. + +#### Understanding the FastAPI Server Startup Process + +```bash +# Method 1: Direct Python execution (includes auto-reload) +python api.py + +# Method 2: Using Uvicorn directly (more control) +uvicorn api:app --host 0.0.0.0 --port 5000 --reload +``` + +When you run this command, here's what happens behind the scenes: + +**1. Python loads your FastAPI application**: +- Imports all required libraries (FastAPI, Pydantic, OpenAI, etc.) +- Loads environment variables from your `.env` file +- Creates the FastAPI application instance with automatic documentation + +**2. Uvicorn configures the ASGI server**: +- Binds to port 5000 with async request handling capabilities +- Sets up request routing with automatic validation +- Enables hot reload for development (restarts on file changes) +- Generates interactive API documentation + +**3. Server starts listening**: +- Your terminal shows: `INFO: Uvicorn running on http://0.0.0.0:5000` +- The server can handle multiple concurrent AI requests +- Your API is ready with automatic docs at `http://localhost:5000/docs` + +#### What You Should See When Everything Works + +```bash +$ python api.py +INFO: Will watch for changes in these directories: ['/your/project/path'] +INFO: Uvicorn running on http://0.0.0.0:5000 (Press CTRL+C to quit) +INFO: Started reloader process [12345] using WatchFiles +INFO: Started server process [12346] +INFO: Waiting for application startup. +INFO: Application startup complete. +``` + +**Understanding the FastAPI output:** +- **Will watch for changes**: Auto-reload enabled for development +- **Uvicorn running**: High-performance ASGI server is active +- **Started reloader process**: File watcher for automatic restarts +- **Application startup complete**: FastAPI app initialized successfully +- **Interactive docs available**: Visit `/docs` for automatic API documentation + +#### Testing Your FastAPI: Multiple Powerful Approaches + +FastAPI provides several convenient ways to test your API, including automatic interactive documentation: + +**Method 1: Interactive API Documentation (Recommended)** +1. Open your browser and go to `http://localhost:5000/docs` +2. You'll see Swagger UI with all your endpoints documented +3. Click on `/hello` β†’ "Try it out" β†’ Enter a test message β†’ "Execute" +4. See the response directly in the browser with proper formatting + +**Method 2: Basic Browser Test** +1. Go to `http://localhost:5000` for the root endpoint +2. Go to `http://localhost:5000/health` to check server health +3. This confirms your FastAPI server is running properly + +**Method 2: Command Line Test (Advanced)** +```bash +# Test with curl (if available) +curl -X POST http://localhost:5000/hello \ + -H "Content-Type: application/json" \ + -d '{"message": "Hello AI!"}' + +# Expected response: +# {"response": "Hello! I'm your AI assistant. How can I help you today?"} +``` + +**Method 3: Python Test Script** +```python +# test_api.py - Create this file to test your API +import requests +import json + +# Test the API endpoint +url = "http://localhost:5000/hello" +data = {"message": "Tell me a joke about programming"} + +response = requests.post(url, json=data) +if response.status_code == 200: + result = response.json() + print("AI Response:", result['response']) +else: + print("Error:", response.status_code, response.text) +``` + +#### Troubleshooting Common Startup Issues + +| Error Message | What It Means | How to Fix | +|---------------|---------------|------------| +| `ModuleNotFoundError: No module named 'fastapi'` | FastAPI not installed | Run `pip install fastapi uvicorn` in your virtual environment | +| `ModuleNotFoundError: No module named 'uvicorn'` | ASGI server not installed | Run `pip install uvicorn` in your virtual environment | +| `KeyError: 'GITHUB_TOKEN'` | Environment variable not found | Check your `.env` file and `load_dotenv()` call | +| `Address already in use` | Port 5000 is busy | Kill other processes using port 5000 or change the port | +| `ValidationError` | Request data doesn't match Pydantic model | Check your request format matches the expected schema | +| `HTTPException 422` | Unprocessable entity | Request validation failed, check `/docs` for correct format | +| `OpenAI API error` | AI service authentication failed | Verify your GitHub token is correct and has proper permissions | + +#### Development Best Practices + +**Hot Reloading**: FastAPI with Uvicorn provides automatic reloading when you save changes to your Python files. This means you can modify your code and test immediately without manually restarting. + +```python +# Enable hot reloading explicitly +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5000, debug=True) # debug=True enables hot reload +``` + +**Logging for Development**: Add logging to understand what's happening: + +```python +import logging + +# Set up logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) @app.route("/hello", methods=["POST"]) def hello(): - # get message from request body { "message": "do this taks for me" } data = request.get_json() message = data.get("message", "") + + logger.info(f"Received message: {message}") + + if not message: + logger.warning("Empty message received") + return jsonify({"error": "Message field is required"}), 400 + + try: + response = call_llm(message, "You are a helpful and friendly assistant.") + logger.info(f"AI response generated successfully") + return jsonify({"response": response}) + except Exception as e: + logger.error(f"AI API error: {str(e)}") + return jsonify({"error": "AI service temporarily unavailable"}), 500 +``` - response = call_llm(message, "You are a helpful assistant.") - return jsonify({ - "response": response - }) +**Why logging helps**: During development, you can see exactly what requests are coming in, what the AI is responding with, and where errors occur. This makes debugging much faster. -if __name__ == "__main__": - app.run(host="0.0.0.0", port=5000) +### Configuring for GitHub Codespaces: Cloud Development Made Easy + +GitHub Codespaces is like having a powerful development computer in the cloud that you can access from any browser. If you're working in Codespaces, there are a few additional steps to make your backend accessible to your frontend. + +#### Understanding Codespaces Networking + +In a local development environment, everything runs on the same computer: +- Backend: `http://localhost:5000` +- Frontend: `http://localhost:3000` (or file://) + +In Codespaces, your development environment runs on GitHub's servers, so "localhost" has a different meaning. GitHub automatically creates public URLs for your services, but you need to configure them properly. + +#### Step-by-Step Codespaces Configuration + +**1. Start your backend server**: +```bash +cd backend +python api.py ``` -Here, we create a flask API and define a default route "/" and "/chat". The latter is meant to be used by our frontend to pass questions to it. +You'll see the familiar FastAPI/Uvicorn startup message, but notice it's running inside the Codespace environment. -To integrate *llm.py* here's what we need to do: +**2. Configure port visibility**: +- Look for the "Ports" tab in the bottom panel of VS Code +- Find port 5000 in the list +- Right-click on port 5000 +- Select "Port Visibility" β†’ "Public" -- Import the `call_llm` function: +**Why make it public?** By default, Codespace ports are private (only accessible to you). Making it public allows your frontend (which runs in the browser) to communicate with your backend. - ```python - from llm import call_llm - from flask import Flask, request - ``` +**3. Get your public URL**: +After making the port public, you'll see a URL like: +``` +https://your-codespace-name-5000.app.github.dev +``` -- Call it from the "/chat" route: +**4. Update your frontend configuration**: +```javascript +// In your frontend app.js, update the BASE_URL: +this.BASE_URL = "https://your-codespace-name-5000.app.github.dev"; +``` - ```python - @app.route("/hello", methods=["POST"]) - def hello(): - # get message from request body { "message": "do this taks for me" } - data = request.get_json() - message = data.get("message", "") +#### Understanding Codespace URLs - response = call_llm(message, "You are a helpful assistant.") - return jsonify({ - "response": response - }) - ``` +Codespace URLs follow a predictable pattern: +``` +https://[codespace-name]-[port].app.github.dev +``` - Here we parse the incoming request to retrieve the `message` property from the JSON body. Thereafter we call the LLM with this call: +**Breaking this down:** +- `codespace-name`: A unique identifier for your Codespace (usually includes your username) +- `port`: The port number your service is running on (5000 for our FastAPI app) +- `app.github.dev`: GitHub's domain for Codespace applications - ```python - response = call_llm(message, "You are a helpful assistant") +#### Testing Your Codespace Setup - # return the response as JSON - return jsonify({ - "response": response - }) - ``` +**1. Test the backend directly**: +Open your public URL in a new browser tab. You should see: +``` +Welcome to the AI Chat API. Send POST requests to /hello with JSON payload containing 'message' field. +``` -Great, now we have done what we need. +**2. Test with browser developer tools**: +```javascript +// Open browser console and test your API +fetch('https://your-codespace-name-5000.app.github.dev/hello', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({message: 'Hello from Codespaces!'}) +}) +.then(response => response.json()) +.then(data => console.log(data)); +``` -## Configure Cors +#### Codespaces vs Local Development -We should call out that we set up something like CORS, cross-origin resource sharing. This means that because our backend and frontend will ron on different ports, we need to allow the frontend to call into the backend. +| Aspect | Local Development | GitHub Codespaces | +|--------|-------------------|-------------------| +| **Setup Time** | Longer (install Python, dependencies) | Instant (pre-configured environment) | +| **URL Access** | `http://localhost:5000` | `https://xyz-5000.app.github.dev` | +| **Port Configuration** | Automatic | Manual (make ports public) | +| **File Persistence** | Local machine | GitHub repository | +| **Collaboration** | Difficult to share environment | Easy to share Codespace link | +| **Internet Dependency** | Only for AI API calls | Required for everything | -### Using Python +#### Codespace Development Tips -There's a piece of code in *api.py* that sets this up: +**Environment Variables in Codespaces**: +Your `.env` file works the same way in Codespaces, but you can also set environment variables directly in the Codespace: -```python -from flask_cors import CORS +```bash +# Set environment variable for the current session +export GITHUB_TOKEN="your_token_here" -app = Flask(__name__) -CORS(app) # * example.com +# Or add to your .bashrc for persistence +echo 'export GITHUB_TOKEN="your_token_here"' >> ~/.bashrc ``` -Right now it's been set up to allow "*" which is all origins and that's a bit unsafe, we should restrict it once we go to production. +**Port Management**: +- Codespaces automatically detects when your application starts listening on a port +- You can forward multiple ports simultaneously (useful if you add a database later) +- Ports remain accessible as long as your Codespace is running -## Run your project +**Development Workflow**: +1. Make code changes in VS Code +2. FastAPI auto-reloads (thanks to Uvicorn's reload mode) +3. Test changes immediately through the public URL +4. Commit and push when ready -To run your project, you need to start up your backend first and then your frontend. +> πŸ’‘ **Pro Tip**: Bookmark your Codespace backend URL during development. Since Codespace names are stable, the URL won't change as long as you're using the same Codespace. -### Using Python +## Creating the Frontend Chat Interface: Where Humans Meet AI -Ok, so we have *llm.py* and *api.py*, how can we make this work with a backend? Well, there's two things we need to do: +Now that our backend API is running and serving AI responses, it's time to create the human-facing part of our application – the frontend. This is where web development artistry meets user experience design. We're not just building a form that sends data; we're creating an interface that makes talking to AI feel natural, responsive, and enjoyable. -- Install dependencies: +### Understanding Frontend Architecture in Modern Web Development - ```sh - cd backend - python -m venv venv - source ./venv/bin/activate +Our frontend will be what developers call a "Single Page Application" (SPA). Unlike traditional websites that reload entire pages, our chat interface updates dynamically as users interact with it: - pip install openai flask flask-cors openai - ``` +**Traditional websites**: Like flipping through a book – each "page" is a separate HTML file +**Single Page Apps**: Like using a smartphone app – the interface updates fluidly without full page reloads -- Start the API +```mermaid +graph TD + A[User Types Message] --> B[JavaScript Captures Input] + B --> C[Validate & Format Data] + C --> D[Send to Backend API] + D --> E[Display Loading State] + E --> F[Receive AI Response] + F --> G[Update Chat Interface] + G --> H[Ready for Next Message] +``` - ```sh - python api.py - ``` +### The Three Pillars of Frontend Development + +Every frontend application, from simple websites to complex apps like Discord or Slack, is built on three fundamental technologies: + +**HTML (Structure)**: The skeleton of your application +- Defines what elements exist (buttons, text areas, containers) +- Provides semantic meaning (this is a header, this is a form, etc.) +- Creates the foundation that CSS and JavaScript build upon + +**CSS (Presentation)**: The styling and visual design +- Controls how everything looks (colors, fonts, layouts) +- Handles responsive design (how it looks on phones vs computers) +- Creates animations and interactive visual feedback + +**JavaScript (Behavior)**: The dynamic functionality +- Handles user interactions (clicks, typing, scrolling) +- Manages data flow between frontend and backend +- Updates the interface in real-time without page reloads + +**Think of it like building a house:** +- **HTML**: The frame and rooms (structure) +- **CSS**: The paint, furniture, and decoration (appearance) +- **JavaScript**: The electricity, plumbing, and smart home features (functionality) - If you're in Codespaces you need to go to Ports in the bottom part of the editor, right-click over it and click Port Visibility" and select "Public". +### Why Modern JavaScript Architecture Matters -### Work on a frontend +Our chat application will use modern JavaScript patterns that you'll see in professional applications. Understanding these concepts will help you as you grow as a developer: -Now that we have an API up and running, let's create a frontend for this. A bare minimum frontend that we will improve stepwise. In a *frontend* folder, create the following: +**Class-Based Architecture**: We'll organize our code into classes, which is like creating blueprints for objects +**Async/Await**: Modern way to handle operations that take time (like API calls) +**Event-Driven Programming**: Our app responds to user actions (clicks, key presses) rather than running in a loop +**DOM Manipulation**: Dynamically updating the webpage content based on user interactions and API responses + +### Project Structure Setup + +Create a frontend directory with this organized structure: ```text -backend/ frontend/ -index.html -app.js -styles.css +β”œβ”€β”€ index.html # Main HTML structure +β”œβ”€β”€ app.js # JavaScript functionality +└── styles.css # Visual styling ``` -Let's start with **index.html**: +**Understanding the architecture:** +- **Separates** concerns between structure (HTML), behavior (JavaScript), and presentation (CSS) +- **Maintains** a simple file structure that's easy to navigate and modify +- **Follows** web development best practices for organization and maintainability + +### Building the HTML Foundation: Semantic Structure for Accessibility + +Let's start with the HTML structure. Modern web development emphasizes "semantic HTML" – using HTML elements that clearly describe their purpose, not just their appearance. This makes your application accessible to screen readers, search engines, and other tools. + +**Why semantic HTML matters**: Imagine describing your chat app to someone over the phone. You'd say "there's a header with the title, a main area where conversations appear, and a form at the bottom for typing messages." Semantic HTML uses elements that match this natural description. + +Create `index.html` with this thoughtfully structured markup: ```html - - - - - -
- - - -
- + + ``` -This above is the absolute minimum you need to support a chat window, as it consists of a textarea where messages will be rendered, an input for where to type the message and a button for sending your message to the backend. Let's look at the JavaScript next in *app.js* +**Understanding each HTML element and its purpose:** + +#### Document Structure +- **``**: Tells the browser this is modern HTML5 +- **``**: Specifies the page language for screen readers and translation tools +- **``**: Ensures proper character encoding for international text +- **``**: Makes the page mobile-responsive by controlling zoom and scale + +#### Semantic Elements +- **`
`**: Clearly identifies the top section with title and description +- **`
`**: Designates the primary content area (where conversations happen) +- **`
`**: Semantically correct for user input, enables proper keyboard navigation + +#### Accessibility Features +- **`role="log"`**: Tells screen readers this area contains a chronological log of messages +- **`aria-live="polite"`**: Announces new messages to screen readers without interrupting +- **`aria-label`**: Provides descriptive labels for form controls +- **`required`**: Browser validates that users enter a message before sending + +#### CSS and JavaScript Integration +- **`class` attributes**: Provide styling hooks for CSS (e.g., `chat-container`, `input-group`) +- **`id` attributes**: Allow JavaScript to find and manipulate specific elements +- **Script placement**: JavaScript file loaded at the end so HTML loads first + +**Why this structure works:** +- **Logical flow**: Header β†’ Main content β†’ Input form matches natural reading order +- **Keyboard accessible**: Users can tab through all interactive elements +- **Screen reader friendly**: Clear landmarks and descriptions for visually impaired users +- **Mobile responsive**: Viewport meta tag enables responsive design +- **Progressive enhancement**: Works even if CSS or JavaScript fails to load + +### Adding Interactive JavaScript: Modern Web Application Logic + +Now let's build the JavaScript that brings our chat interface to life. We'll use modern JavaScript patterns that you'll encounter in professional web development, including ES6 classes, async/await, and event-driven programming. + +#### Understanding Modern JavaScript Architecture + +Instead of writing procedural code (a series of functions that run in order), we'll create a **class-based architecture**. Think of a class as a blueprint for creating objects – like how an architect's blueprint can be used to build multiple houses. + +**Why use classes for web applications?** +- **Organization**: All related functionality is grouped together +- **Reusability**: You could create multiple chat instances on the same page +- **Maintainability**: Easier to debug and modify specific features +- **Professional standard**: This pattern is used in frameworks like React, Vue, and Angular + +Create `app.js` with this modern, well-structured JavaScript: + +```javascript +// app.js - Modern chat application logic + +class ChatApp { + constructor() { + // Get references to DOM elements we'll need to manipulate + this.messages = document.getElementById("messages"); + this.form = document.getElementById("chatForm"); + this.input = document.getElementById("messageInput"); + this.sendButton = document.getElementById("sendBtn"); + + // Configure your backend URL here + this.BASE_URL = "http://localhost:5000"; // Update this for your environment + this.API_ENDPOINT = `${this.BASE_URL}/hello`; + + // Set up event listeners when the chat app is created + this.initializeEventListeners(); + } + + initializeEventListeners() { + // Listen for form submission (when user clicks Send or presses Enter) + this.form.addEventListener("submit", (e) => this.handleSubmit(e)); + + // Also listen for Enter key in the input field (better UX) + this.input.addEventListener("keypress", (e) => { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault(); + this.handleSubmit(e); + } + }); + } + + async handleSubmit(event) { + event.preventDefault(); // Prevent form from refreshing the page + + const messageText = this.input.value.trim(); + if (!messageText) return; // Don't send empty messages + + // Provide user feedback that something is happening + this.setLoading(true); + + // Add user message to chat immediately (optimistic UI) + this.appendMessage(messageText, "user"); + + // Clear input field so user can type next message + this.input.value = ''; + + try { + // Call the AI API and wait for response + const reply = await this.callAPI(messageText); + + // Add AI response to chat + this.appendMessage(reply, "assistant"); + } catch (error) { + console.error('API Error:', error); + this.appendMessage("Sorry, I'm having trouble connecting right now. Please try again.", "error"); + } finally { + // Re-enable the interface regardless of success or failure + this.setLoading(false); + } + } + + async callAPI(message) { + const response = await fetch(this.API_ENDPOINT, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ message }) + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + return data.response; + } + + appendMessage(text, role) { + const messageElement = document.createElement("div"); + messageElement.className = `message ${role}`; + messageElement.innerHTML = ` +
+ ${this.escapeHtml(text)} + ${new Date().toLocaleTimeString()} +
+ `; + + this.messages.appendChild(messageElement); + this.scrollToBottom(); + } + + escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; + } + + scrollToBottom() { + this.messages.scrollTop = this.messages.scrollHeight; + } + + setLoading(isLoading) { + this.sendButton.disabled = isLoading; + this.input.disabled = isLoading; + this.sendButton.textContent = isLoading ? "Sending..." : "Send"; + } +} -**app.js** +// Initialize the chat application when the page loads +document.addEventListener("DOMContentLoaded", () => { + new ChatApp(); +}); +``` -```js -// app.js +#### Understanding Each JavaScript Concept + +**ES6 Class Structure**: +```javascript +class ChatApp { + constructor() { + // This runs when you create a new ChatApp instance + // It's like the "setup" function for your chat + } + + methodName() { + // Methods are functions that belong to the class + // They can access class properties using "this" + } +} +``` -(function(){ - // 1. set up elements - const messages = document.getElementById("messages"); - const form = document.getElementById("form"); - const input = document.getElementById("input"); +**Async/Await Pattern**: +```javascript +// Old way (callback hell): +fetch(url) + .then(response => response.json()) + .then(data => console.log(data)) + .catch(error => console.error(error)); + +// Modern way (async/await): +try { + const response = await fetch(url); + const data = await response.json(); + console.log(data); +} catch (error) { + console.error(error); +} +``` - const BASE_URL = "change this"; - const API_ENDPOINT = `${BASE_URL}/hello`; +**Event-Driven Programming**: +Instead of constantly checking if something happened, we "listen" for events: +```javascript +// When form is submitted, run handleSubmit +this.form.addEventListener("submit", (e) => this.handleSubmit(e)); - // 2. create a function that talks to our backend - async function callApi(text) { - const response = await fetch(API_ENDPOINT, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ message: text }) - }); - let json = await response.json(); - return json.response; - } +// When Enter key is pressed, also run handleSubmit +this.input.addEventListener("keypress", (e) => { /* ... */ }); +``` - // 3. add response to our textarea - function appendMessage(text, role) { - const el = document.createElement("div"); - el.className = `message ${role}`; - el.innerHTML = text; - messages.appendChild(el); - } +**DOM Manipulation**: +```javascript +// Create new elements +const messageElement = document.createElement("div"); - // 4. listen to submit events - form.addEventListener("submit", async(e) => { - e.preventDefault(); - // someone clicked the button in the form - - // get input - const text = input.value.trim(); +// Modify their properties +messageElement.className = "message user"; +messageElement.innerHTML = "Hello world!"; - appendMessage(text, "user") +// Add to the page +this.messages.appendChild(messageElement); +``` - // reset it - input.value = ''; +#### Security and Best Practices - const reply = await callApi(text); +**XSS Prevention**: +```javascript +escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; // This automatically escapes HTML + return div.innerHTML; +} +``` - // add to messages - appendMessage(reply, "assistant"); +**Why this matters**: If a user types ``, this function ensures it displays as text rather than executing as code. - }) -})(); +**Error Handling**: +```javascript +try { + const reply = await this.callAPI(messageText); + this.appendMessage(reply, "assistant"); +} catch (error) { + // Show user-friendly error instead of breaking the app + this.appendMessage("Sorry, I'm having trouble...", "error"); +} ``` -Let's go through the code per section: +**User Experience Considerations**: +- **Optimistic UI**: Add user message immediately, don't wait for server response +- **Loading states**: Disable buttons and show "Sending..." while waiting +- **Auto-scroll**: Keep newest messages visible +- **Input validation**: Don't send empty messages +- **Keyboard shortcuts**: Enter key sends messages (like real chat apps) -- 1) Here we get a reference to all our elements we will refer to later in the code -- 2) In this section, we create a function that uses the built-in `fetch` method that calls our backend -- 3) `appendMessage` helps add responses as well as what you as a user type. -- 4) Here we listen to the submit event and we end up reading the input field, place the user's message in the text area, call the API, render that respond in the text area. +#### Understanding the Application Flow -Let's look at styling next, here's where you can go really crazy and make it look like you want, but here's some suggestions: +1. **Page loads** β†’ `DOMContentLoaded` event fires β†’ `new ChatApp()` created +2. **Constructor runs** β†’ Gets DOM element references β†’ Sets up event listeners +3. **User types message** β†’ Presses Enter or clicks Send β†’ `handleSubmit` runs +4. **handleSubmit** β†’ Validates input β†’ Shows loading state β†’ Calls API +5. **API responds** β†’ Add AI message to chat β†’ Re-enable interface +6. **Ready for next message** β†’ User can continue chatting -**styles.css** +This architecture is scalable – you could easily add features like message editing, file uploads, or multiple conversation threads without rewriting the core structure. + +### Styling Your Chat Interface + +Now let's create a modern, visually appealing chat interface with CSS. Good styling makes your application feel professional and improves the overall user experience. We'll use modern CSS features like Flexbox, CSS Grid, and custom properties for a responsive, accessible design. + +Create `styles.css` with these comprehensive styles: + +```css +/* styles.css - Modern chat interface styling */ + +:root { + --primary-color: #2563eb; + --secondary-color: #f1f5f9; + --user-color: #3b82f6; + --assistant-color: #6b7280; + --error-color: #ef4444; + --text-primary: #1e293b; + --text-secondary: #64748b; + --border-radius: 12px; + --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + padding: 20px; +} + +.chat-container { + width: 100%; + max-width: 800px; + height: 600px; + background: white; + border-radius: var(--border-radius); + box-shadow: var(--shadow); + display: flex; + flex-direction: column; + overflow: hidden; +} + +.chat-header { + background: var(--primary-color); + color: white; + padding: 20px; + text-align: center; +} + +.chat-header h1 { + font-size: 1.5rem; + margin-bottom: 5px; +} + +.chat-header p { + opacity: 0.9; + font-size: 0.9rem; +} + +.chat-messages { + flex: 1; + padding: 20px; + overflow-y: auto; + display: flex; + flex-direction: column; + gap: 15px; + background: var(--secondary-color); +} -``` .message { - background: #222; - box-shadow: 0 0 0 10px orange; - padding: 10px: - margin: 5px; + display: flex; + max-width: 80%; + animation: slideIn 0.3s ease-out; } .message.user { - background: blue; + align-self: flex-end; +} + +.message.user .message-content { + background: var(--user-color); + color: white; + border-radius: var(--border-radius) var(--border-radius) 4px var(--border-radius); } .message.assistant { - background: grey; -} + align-self: flex-start; +} + +.message.assistant .message-content { + background: white; + color: var(--text-primary); + border-radius: var(--border-radius) var(--border-radius) var(--border-radius) 4px; + border: 1px solid #e2e8f0; +} + +.message.error .message-content { + background: var(--error-color); + color: white; + border-radius: var(--border-radius); +} + +.message-content { + padding: 12px 16px; + box-shadow: var(--shadow); + position: relative; +} + +.message-text { + display: block; + line-height: 1.5; + word-wrap: break-word; +} + +.message-time { + display: block; + font-size: 0.75rem; + opacity: 0.7; + margin-top: 5px; +} + +.chat-form { + padding: 20px; + border-top: 1px solid #e2e8f0; + background: white; +} + +.input-group { + display: flex; + gap: 10px; + align-items: center; +} + +#messageInput { + flex: 1; + padding: 12px 16px; + border: 2px solid #e2e8f0; + border-radius: var(--border-radius); + font-size: 1rem; + outline: none; + transition: border-color 0.2s ease; +} + +#messageInput:focus { + border-color: var(--primary-color); +} + +#messageInput:disabled { + background: #f8fafc; + opacity: 0.6; + cursor: not-allowed; +} + +#sendBtn { + padding: 12px 24px; + background: var(--primary-color); + color: white; + border: none; + border-radius: var(--border-radius); + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: background-color 0.2s ease; + min-width: 80px; +} + +#sendBtn:hover:not(:disabled) { + background: #1d4ed8; +} + +#sendBtn:disabled { + background: #94a3b8; + cursor: not-allowed; +} + +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Responsive design for mobile devices */ +@media (max-width: 768px) { + body { + padding: 10px; + } + + .chat-container { + height: calc(100vh - 20px); + border-radius: 8px; + } + + .message { + max-width: 90%; + } + + .input-group { + flex-direction: column; + gap: 10px; + } + + #messageInput { + width: 100%; + } + + #sendBtn { + width: 100%; + } +} + +/* Accessibility improvements */ +@media (prefers-reduced-motion: reduce) { + .message { + animation: none; + } + + * { + transition: none !important; + } +} + +/* Dark mode support */ +@media (prefers-color-scheme: dark) { + .chat-container { + background: #1e293b; + color: #f1f5f9; + } + + .chat-messages { + background: #0f172a; + } + + .message.assistant .message-content { + background: #334155; + color: #f1f5f9; + border-color: #475569; + } + + .chat-form { + background: #1e293b; + border-color: #475569; + } + + #messageInput { + background: #334155; + color: #f1f5f9; + border-color: #475569; + } +} ``` -With these three classes, you will style messages different depending on where they come from an assistant or you as a user. If you want to be inspired, check out the `solution/frontend/styles.css` folder. +**Understanding the CSS architecture:** +- **Uses** CSS custom properties (variables) for consistent theming and easy maintenance +- **Implements** Flexbox layout for responsive design and proper alignment +- **Includes** smooth animations for message appearance without being distracting +- **Provides** visual distinction between user messages, AI responses, and error states +- **Supports** responsive design that works on both desktop and mobile devices +- **Considers** accessibility with reduced motion preferences and proper contrast ratios +- **Offers** dark mode support based on user's system preferences + +### Configuring Your Backend URL -### Change Base Url +The final step is updating the `BASE_URL` in your JavaScript to match your backend server: -There was one thing here we didn't set and that was `BASE_URL`, this is not known until your backend is started. To set it: +```javascript +// For local development +this.BASE_URL = "http://localhost:5000"; -- If you run API locally, it should be set to something like `http://localhost:5000`. -- If run in a Codespaces, it should look something like "[name]app.github.dev". +// For GitHub Codespaces (replace with your actual URL) +this.BASE_URL = "https://your-codespace-name-5000.app.github.dev"; +``` +**Determining your backend URL:** +- **Local development**: Use `http://localhost:5000` if running both frontend and backend locally +- **Codespaces**: Find your backend URL in the Ports tab after making port 5000 public +- **Production**: Replace with your actual domain when deploying to a hosting service +> πŸ’‘ **Testing Tip**: You can test your backend directly by visiting the root URL in your browser. You should see the welcome message from your FastAPI server. + + + +## Testing and Deployment + +Now that you have both frontend and backend components built, let's test everything works together and explore deployment options for sharing your chat assistant with others. + +### Local Testing Workflow + +Follow these steps to test your complete application: + +```mermaid +graph TD + A[Start Backend Server] --> B[Configure Environment Variables] + B --> C[Test API Endpoints] + C --> D[Open Frontend in Browser] + D --> E[Test Chat Functionality] + E --> F[Debug Any Issues] +``` + +**Step-by-step testing process:** + +1. **Start your backend server**: + ```bash + cd backend + source venv/bin/activate # or venv\Scripts\activate on Windows + python api.py + ``` + +2. **Verify the API is working**: + - Open `http://localhost:5000` in your browser + - You should see the welcome message from your FastAPI server + +3. **Open your frontend**: + - Navigate to your frontend directory + - Open `index.html` in your web browser + - Or use VS Code's Live Server extension for better development experience + +4. **Test the chat functionality**: + - Type a message in the input field + - Click "Send" or press Enter + - Verify the AI responds appropriately + - Check browser console for any JavaScript errors + +### Troubleshooting Common Issues + +| Problem | Symptoms | Solution | +|---------|----------|----------| +| **CORS Error** | Frontend can't reach backend | Ensure FastAPI CORSMiddleware is properly configured | +| **API Key Error** | 401 Unauthorized responses | Check your `GITHUB_TOKEN` environment variable | +| **Connection Refused** | Network errors in frontend | Verify backend URL and that Flask server is running | +| **No AI Response** | Empty or error responses | Check backend logs for API quota or authentication issues | + +**Common debugging steps:** +- **Checks** browser Developer Tools Console for JavaScript errors +- **Verifies** Network tab shows successful API requests and responses +- **Reviews** backend terminal output for Python errors or API issues +- **Confirms** environment variables are properly loaded and accessible ## GitHub Copilot Agent Challenge πŸš€ @@ -342,55 +1849,256 @@ Use the Agent mode to complete the following challenge: **Prompt:** Modify the chat application to include conversation history that persists between sessions. Add functionality to save chat messages to local storage, display conversation history when the page loads, and include a "Clear History" button. Also implement typing indicators and message timestamps to make the chat experience more realistic. -## Assignment +## Assignment: Build Your Personal AI Assistant + +Now it's time to create your own customized version of the chat assistant! This assignment will help you apply everything you've learned while encouraging creativity and personalization. + +### Project Requirements -Create your own folder *project* with content like so: +Create your own project folder with this structure: ```text -project/ - frontend/ - index.html - app.js - styles.css - backend/ - ... +my-ai-assistant/ +β”œβ”€β”€ backend/ +β”‚ β”œβ”€β”€ api.py # Flask API server +β”‚ β”œβ”€β”€ llm.py # AI integration functions +β”‚ β”œβ”€β”€ .env # Environment variables (don't commit!) +β”‚ └── requirements.txt # Python dependencies +β”œβ”€β”€ frontend/ +β”‚ β”œβ”€β”€ index.html # Chat interface +β”‚ β”œβ”€β”€ app.js # JavaScript functionality +β”‚ └── styles.css # Custom styling +└── README.md # Your project documentation ``` -Copy the content from what was instructed from above but feel free to customize to your liking +### Core Implementation Tasks + +**Backend Development:** +- **Copy** and customize the Flask API code from the lesson +- **Create** a unique AI personality by modifying the system prompt +- **Add** input validation and error handling to your API endpoints +- **Document** your API endpoints and their expected request/response formats + +**Frontend Development:** +- **Build** the HTML chat interface using semantic markup +- **Implement** the JavaScript chat functionality with modern ES6+ features +- **Design** custom CSS styling that reflects your AI assistant's personality +- **Add** responsive design support for mobile and desktop users + +**Personalization Requirements:** +- **Choose** a unique name and personality for your AI assistant +- **Customize** the visual design (colors, fonts, layout) to match your theme +- **Write** a compelling welcome message and chat header +- **Test** your assistant with various types of questions and conversations + +### Enhancement Ideas (Optional) + +Take your project further with these advanced features: + +| Feature | Description | Skills Practiced | +|---------|-------------|------------------| +| **Message History** | Save conversations to localStorage | Data persistence, JSON handling | +| **Typing Indicators** | Show "AI is typing..." animation | CSS animations, async programming | +| **Message Timestamps** | Display when each message was sent | Date/time formatting, UX design | +| **Export Chat** | Allow users to download conversation history | File handling, data export | +| **Theme Switching** | Light/dark mode toggle | CSS variables, user preferences | +| **Voice Input** | Add speech-to-text functionality | Web APIs, accessibility | + +### Testing and Documentation + +**Quality Assurance:** +- **Test** your application with various input types and edge cases +- **Verify** responsive design works on different screen sizes +- **Check** accessibility with keyboard navigation and screen readers +- **Validate** HTML and CSS for standards compliance + +**Documentation Requirements:** +- **Write** a README.md explaining your project and how to run it +- **Include** screenshots of your chat interface in action +- **Document** any unique features or customizations you added +- **Provide** clear setup instructions for other developers + +### Submission Guidelines + +**Project Deliverables:** +1. Complete project folder with all source code +2. README.md with project description and setup instructions +3. Screenshots demonstrating your chat assistant in action +4. Brief reflection on what you learned and what challenges you faced + +**Evaluation Criteria:** +- **Functionality**: Does the chat assistant work as expected? +- **Code Quality**: Is the code well-organized, commented, and maintainable? +- **Design**: Is the interface visually appealing and user-friendly? +- **Creativity**: How unique and personalized is your implementation? +- **Documentation**: Are setup instructions clear and complete? + +> πŸ’‘ **Success Tip**: Start with the basic requirements first, then add enhancements once everything is working. Focus on creating a polished core experience before adding advanced features. ## Solution [Solution](./solution/README.md) -## Bonus +## Bonus Challenges -Try changing the personality of the AI assistant. +Ready to take your AI assistant to the next level? Try these advanced challenges that will deepen your understanding of AI integration and web development. -### For Python +### Personality Customization + +The real magic happens when you give your AI assistant a unique personality. Experiment with different system prompts to create specialized assistants: + +**Professional Assistant Example:** +```python +call_llm(message, "You are a professional business consultant with 20 years of experience. Provide structured, actionable advice with specific steps and considerations.") +``` -When you call `call_llm` in *api.py* you can change the second argument to what you want, for example: +**Creative Writing Helper Example:** +```python +call_llm(message, "You are an enthusiastic creative writing coach. Help users develop their storytelling skills with imaginative prompts and constructive feedback.") +``` +**Technical Mentor Example:** ```python -call_llm(message, "You are Captain Picard") +call_llm(message, "You are a patient senior developer who explains complex programming concepts using simple analogies and practical examples.") ``` -### Frontend +### Frontend Enhancements + +Transform your chat interface with these visual and functional improvements: + +**Advanced CSS Features:** +- **Implement** smooth message animations and transitions +- **Add** custom chat bubble designs with CSS shapes and gradients +- **Create** a typing indicator animation for when the AI is "thinking" +- **Design** emoji reactions or message rating system + +**JavaScript Enhancements:** +- **Add** keyboard shortcuts (Ctrl+Enter for send, Escape to clear input) +- **Implement** message search and filtering functionality +- **Create** conversation export feature (download as text or JSON) +- **Add** auto-save to localStorage to prevent message loss + +### Advanced AI Integration + +**Multiple AI Personalities:** +- **Create** a dropdown to switch between different AI personalities +- **Save** user's preferred personality in localStorage +- **Implement** context switching that maintains conversation flow + +**Smart Response Features:** +- **Add** conversation context awareness (AI remembers previous messages) +- **Implement** smart suggestions based on conversation topic +- **Create** quick reply buttons for common questions + +> 🎯 **Learning Goal**: These bonus challenges help you understand advanced web development patterns and AI integration techniques that are used in production applications. + +## Summary and Next Steps + +Congratulations! You've successfully built a complete AI-powered chat assistant from scratch. This project has given you hands-on experience with modern web development technologies and AI integration – skills that are increasingly valuable in today's tech landscape. + +### What You've Accomplished + +Throughout this lesson, you've mastered several key technologies and concepts: + +**Backend Development:** +- **Integrated** with GitHub Models API for AI functionality +- **Built** a RESTful API using Flask with proper error handling +- **Implemented** secure authentication using environment variables +- **Configured** CORS for cross-origin requests between frontend and backend + +**Frontend Development:** +- **Created** a responsive chat interface using semantic HTML +- **Implemented** modern JavaScript with async/await and class-based architecture +- **Designed** an engaging user interface with CSS Grid, Flexbox, and animations +- **Added** accessibility features and responsive design principles + +**Full-Stack Integration:** +- **Connected** frontend and backend through HTTP API calls +- **Handled** real-time user interactions and asynchronous data flow +- **Implemented** error handling and user feedback throughout the application +- **Tested** the complete application workflow from user input to AI response + +### Key Learning Outcomes + +```mermaid +mindmap + root((AI Chat App Skills)) + API Integration + Authentication + Error Handling + Async Programming + Web Development + HTML5 Semantics + Modern CSS + ES6+ JavaScript + User Experience + Responsive Design + Accessibility + Real-time Interaction + AI Understanding + Prompt Engineering + Model Parameters + Conversation Flow +``` + +This project has introduced you to the fundamentals of building AI-powered applications, which represents the future of web development. You now understand how to integrate AI capabilities into traditional web applications, creating engaging user experiences that feel intelligent and responsive. + +### Professional Applications + +The skills you've developed in this lesson are directly applicable to modern software development careers: + +- **Full-stack web development** using modern frameworks and APIs +- **AI integration** in web applications and mobile apps +- **API design and development** for microservices architectures +- **User interface development** with focus on accessibility and responsive design +- **DevOps practices** including environment configuration and deployment + +### Continuing Your AI Development Journey + +**Next Learning Steps:** +- **Explore** more advanced AI models and APIs (GPT-4, Claude, Gemini) +- **Learn** about prompt engineering techniques for better AI responses +- **Study** conversation design and chatbot user experience principles +- **Investigate** AI safety, ethics, and responsible AI development practices +- **Build** more complex applications with conversation memory and context awareness + +**Advanced Project Ideas:** +- Multi-user chat rooms with AI moderation +- AI-powered customer service chatbots +- Educational tutoring assistants with personalized learning +- Creative writing collaborators with different AI personalities +- Technical documentation assistants for developers + +## Getting Started with GitHub Codespaces -Change also the CSS and text to your liking, so do changes in *index.html* and *styles.css*. +Want to try this project in a cloud development environment? GitHub Codespaces provides a complete development setup in your browser, perfect for experimenting with AI applications without local setup requirements. -## Summary +### Setting Up Your Development Environment -Great, you've learned from scratch how to create a personal assistant using AI. We've done so using GitHub Models, a backend in Python and a frontend in HTML, CSS and JavaScript +**Step 1: Create from Template** +- **Navigate** to the [Web Dev For Beginners repository](https://github.com/microsoft/Web-Dev-For-Beginners) +- **Click** "Use this template" in the top-right corner (ensure you're logged into GitHub) -## Set up with Codespaces +![Create from template interface showing the green "Use this template" button](./assets/template.png) -- Navigate to: [Web Dev For Beginners repo](https://github.com/microsoft/Web-Dev-For-Beginners) -- Create from a template (make sure you're logged in to GitHub) in top-right corner: +**Step 2: Launch Codespaces** +- **Open** your newly created repository +- **Click** the green "Code" button and select "Codespaces" +- **Choose** "Create codespace on main" to start your development environment - ![Create from template](./assets/template.png) +![Create codespace interface with options for launching cloud development environment](./assets/codespace.png) -- Once in your repo, create a Codespace: +**Step 3: Environment Configuration** +Once your Codespace loads, you'll have access to: +- **Pre-installed** Python, Node.js, and all necessary development tools +- **VS Code interface** with extensions for web development +- **Terminal access** for running backend and frontend servers +- **Port forwarding** for testing your applications - ![Create codespace](./assets/codespace.png) +**What Codespaces provides:** +- **Eliminates** local environment setup and configuration issues +- **Provides** consistent development environment across different devices +- **Includes** pre-configured tools and extensions for web development +- **Offers** seamless integration with GitHub for version control and collaboration - This should start an environment you can now work with. +> πŸš€ **Pro Tip**: Codespaces is perfect for learning and prototyping AI applications since it handles all the complex environment setup automatically, letting you focus on building and learning rather than configuration troubleshooting. diff --git a/9-chat-project/solution/backend/python/README.md b/9-chat-project/solution/backend/python/README.md index 2fffe206..114610f6 100644 --- a/9-chat-project/solution/backend/python/README.md +++ b/9-chat-project/solution/backend/python/README.md @@ -1,7 +1,5 @@ # Run code - - ## Set up Create virtual environment @@ -14,15 +12,23 @@ source ./venv/bin/activate ## Install dependencies ```sh -pip install openai flask flask-cors +pip install openai fastapi uvicorn python-dotenv ``` ## Run API ```sh +# Method 1: Direct execution python api.py + +# Method 2: Using uvicorn +uvicorn api:app --host 0.0.0.0 --port 5000 --reload ``` +## Test API + +Visit the interactive API documentation at: `http://localhost:5000/docs` + ## Run frontend Make sure you stand in the frontend folder diff --git a/9-chat-project/solution/backend/python/api.py b/9-chat-project/solution/backend/python/api.py index 9ac5828a..941d3dcf 100644 --- a/9-chat-project/solution/backend/python/api.py +++ b/9-chat-project/solution/backend/python/api.py @@ -1,56 +1,84 @@ -from flask import Flask, request, jsonify +from fastapi import FastAPI, HTTPException +from fastapi.middleware.cors import CORSMiddleware +from pydantic import BaseModel from llm import call_llm -from flask_cors import CORS import logging -app = Flask(__name__) +# Configure logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +# Create FastAPI application +app = FastAPI( + title="AI Chat API", + description="A high-performance API for AI-powered chat applications", + version="1.0.0" +) # Configure CORS (allow all origins for development; restrict in production) -CORS(app, resources={r"/*": {"origins": "*"}}) +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) -# Set up logging -logging.basicConfig(level=logging.INFO) +# Pydantic models for request/response validation +class ChatMessage(BaseModel): + message: str + +class ChatResponse(BaseModel): + response: str + +class HealthResponse(BaseModel): + status: str + service: str -@app.route("/", methods=["GET"]) -def index(): +@app.get("/") +async def index(): """Root endpoint for API status.""" - return jsonify({ + return { "status": "ok", - "message": "Welcome to the Chat Project API" - }) + "message": "Welcome to the Chat Project API", + "docs": "/docs", + "health": "/health" + } -@app.route("/health", methods=["GET"]) -def health(): +@app.get("/health", response_model=HealthResponse) +async def health(): """Health check endpoint.""" - return jsonify({"status": "healthy"}), 200 + return HealthResponse(status="healthy", service="ai-chat-api") -@app.route("/test", methods=["GET"]) -def test(): +@app.get("/test") +async def test(): """Simple test endpoint.""" - return jsonify({"result": "Test successful"}), 200 + return {"result": "Test successful"} -@app.route("/hello", methods=["POST"]) -def hello(): +@app.post("/hello", response_model=ChatResponse) +async def hello(chat_message: ChatMessage): """ Chat endpoint. Expects JSON: { "message": "your message" } Returns: { "response": "LLM response" } """ try: - data = request.get_json(force=True) - message = data.get("message", "").strip() + message = chat_message.message.strip() if not message: - logging.warning("No message provided in request.") - return jsonify({"error": "No message provided."}), 400 + logger.warning("Empty message provided in request.") + raise HTTPException(status_code=400, detail="Message cannot be empty") - logging.info(f"Received message: {message}") + logger.info(f"Received message: {message}") response = call_llm(message, "You are a helpful assistant.") - return jsonify({"response": response}), 200 + logger.info("LLM response generated successfully") + return ChatResponse(response=response) + except HTTPException: + raise except Exception as e: - logging.error(f"Error in /hello endpoint: {e}") - return jsonify({"error": "Internal server error."}), 500 + logger.error(f"Error in /hello endpoint: {e}") + raise HTTPException(status_code=500, detail="Internal server error") if __name__ == "__main__": - # Run the app with debug mode for development - app.run(host="0.0.0.0", port=5000, debug=True) \ No newline at end of file + import uvicorn + uvicorn.run(app, host="0.0.0.0", port=5000, reload=True) \ No newline at end of file