diff --git a/modules/friday-core/README.md b/modules/friday-core/README.md index e69de29..b31903d 100644 --- a/modules/friday-core/README.md +++ b/modules/friday-core/README.md @@ -0,0 +1,31 @@ +# Friday Core + +This module is the starting point for building a Friday-style assistant stack for The Stark Project. + +## LLM Direction + +The LLM work lives under [src/llm](src/llm). The initial design focuses on a modular assistant architecture with: + +- a model interface layer +- a chat inference service +- a tool-routing layer for plugins and actions +- a future training pipeline for fine-tuning and adaptation + +## Current Structure + +- [src/llm/README.md](src/llm/README.md) — high-level architecture, roadmap, and technical decisions +- [src/llm/core/model_interface.py](src/llm/core/model_interface.py) — base model and prompt wrapper abstractions +- [src/llm/inference/chat_service.py](src/llm/inference/chat_service.py) — minimal chat orchestration layer +- [src/llm/agents/tool_router.py](src/llm/agents/tool_router.py) — tool registration and dispatch + +## Recommended Next Steps + +1. Add a concrete backend implementation such as a Hugging Face model wrapper. +2. Connect the assistant to the existing memory subsystem. +3. Add a small plugin for a useful action like web lookup or command execution. +4. Introduce a retrieval layer for long-term context. +5. Build evaluation and safety checks for assistant behavior. + +## Vision + +The goal is to evolve this module into an assistant that feels like a Tony Stark-style companion: proactive, context-aware, connected to tools, and capable of acting across the Stark ecosystem. diff --git a/modules/friday-core/src/llm/README.md b/modules/friday-core/src/llm/README.md new file mode 100644 index 0000000..26e75d4 --- /dev/null +++ b/modules/friday-core/src/llm/README.md @@ -0,0 +1,94 @@ +# Friday Core LLM Workspace + +This folder defines the initial architecture for building a custom assistant stack inspired by the Tony Stark / Friday concept: a fast, multimodal, context-aware assistant with tool use, memory, and safety boundaries. + +## Goals + +- Build a compact, trainable language model foundation for conversational assistance. +- Add orchestration layers for memory, tools, and action execution. +- Keep the design modular so it can evolve from local experiments to a production-grade assistant. + +## Proposed Structure + +- core/: shared tokenizer, config, model interfaces, and runtime utilities. +- models/: model definitions, checkpoints, and architecture variants. +- training/: data pipelines, tokenizer training, pretraining and fine-tuning scripts. +- inference/: serving, batching, streaming, and prompt execution logic. +- agents/: planner/executor patterns for tool-calling and multi-step reasoning. + +## Recommended Infrastructure + +### 1. Runtime +- Python 3.11+ +- PyTorch or JAX for training and inference +- Hugging Face Transformers for rapid prototyping +- vLLM or TensorRT-LLM for optimized serving later + +### 2. Data and Memory +- Structured memory store for long-term facts +- Episodic memory for recent conversations +- Vector database for semantic retrieval +- Event bus integration for tool and sensor subscriptions + +### 3. Tooling and Services +- Plugin interface for commands, APIs, and device control +- Safety policy layer before action execution +- Logging and observability for prompts, tool calls, and errors + +### 4. Deployment +- Local development first +- Containerized inference service +- Optional GPU-backed training environment +- Edge deployment path for low-latency assistant use + +## Phased Roadmap + +### Phase 1: Foundations +- Define the model interface and configuration schema +- Build tokenizer and prompt templates +- Create a minimal inference loop +- Wire the assistant to the existing memory and plugin layers + +### Phase 2: Capability Expansion +- Add retrieval-augmented generation +- Introduce tool calling and function routing +- Support multimodal inputs such as voice and visual context +- Add conversation state management + +### Phase 3: Personality and Alignment +- Fine-tune on domain-specific assistant behavior +- Add safety policies and refusal handling +- Improve memory selection and personalization +- Optimize latency and response quality + +### Phase 4: Stark-like Assistant Experience +- High-speed voice interaction +- Context-aware proactive suggestions +- Multi-agent collaboration for planning and execution +- Deep integration with robotics, dashboards, and hardware tools + +## Technical Decisions + +### Why a modular architecture? +A modular design allows you to experiment with model variants without rewriting the assistant runtime. + +### Why start with a small foundation model? +A smaller model is easier to iterate on and is ideal for local development before scaling to larger architectures. + +### Why separate training and inference? +Training and inference have different dependencies, performance characteristics, and deployment constraints. + +### Why integrate memory and tools early? +An assistant feels intelligent when it can recall context and perform actions, not just generate text. + +## Suggested First Implementation + +1. Create a minimal model wrapper class. +2. Add a prompt builder for system, user, and tool context. +3. Connect the LLM to a simple in-memory conversation store. +4. Add one tool plugin such as a weather lookup or command runner. +5. Expose a basic chat endpoint. + +## Notes + +This is an initial blueprint. The long-term ambition is a Friday-like assistant that can reason, remember, act, and coordinate across the Stark ecosystem. diff --git a/modules/friday-core/src/llm/agents/tool_router.py b/modules/friday-core/src/llm/agents/tool_router.py new file mode 100644 index 0000000..2cfa452 --- /dev/null +++ b/modules/friday-core/src/llm/agents/tool_router.py @@ -0,0 +1,19 @@ +from typing import Callable, Dict, List + + +class ToolRouter: + """Routes tool calls from LLM outputs to plugin handlers.""" + + def __init__(self) -> None: + self.tools: Dict[str, Callable[..., str]] = {} + + def register(self, name: str, handler: Callable[..., str]) -> None: + self.tools[name] = handler + + def route(self, tool_name: str, *args, **kwargs) -> str: + if tool_name not in self.tools: + raise KeyError(f"Tool '{tool_name}' is not registered") + return self.tools[tool_name](*args, **kwargs) + + def list_tools(self) -> List[str]: + return sorted(self.tools.keys()) diff --git a/modules/friday-core/src/llm/core/model_interface.py b/modules/friday-core/src/llm/core/model_interface.py new file mode 100644 index 0000000..da38713 --- /dev/null +++ b/modules/friday-core/src/llm/core/model_interface.py @@ -0,0 +1,41 @@ +from dataclasses import dataclass +from typing import Any, Dict, List, Optional + + +@dataclass +class ModelConfig: + name: str = "friday-mini" + max_context_length: int = 4096 + temperature: float = 0.7 + top_p: float = 0.95 + max_new_tokens: int = 512 + + +class LLMBackend: + """Abstract interface for any LLM backend used by Friday Core.""" + + def __init__(self, config: Optional[ModelConfig] = None) -> None: + self.config = config or ModelConfig() + + def generate(self, prompt: str, **kwargs: Any) -> str: + raise NotImplementedError + + def stream_generate(self, prompt: str, **kwargs: Any): + raise NotImplementedError + + +class FridayLLM: + """High-level wrapper that will connect the runtime to models, memory, and tools.""" + + def __init__(self, backend: LLMBackend) -> None: + self.backend = backend + + def chat(self, message: str, history: Optional[List[Dict[str, str]]] = None) -> str: + prompt = self._build_prompt(message, history or []) + return self.backend.generate(prompt) + + def _build_prompt(self, message: str, history: List[Dict[str, str]]) -> str: + conversation = "\n".join( + f"{entry['role']}: {entry['content']}" for entry in history + ) + return f"system: You are Friday, an assistant for The Stark Project.\n{conversation}\nuser: {message}\nassistant:" diff --git a/modules/friday-core/src/llm/inference/chat_service.py b/modules/friday-core/src/llm/inference/chat_service.py new file mode 100644 index 0000000..8f36088 --- /dev/null +++ b/modules/friday-core/src/llm/inference/chat_service.py @@ -0,0 +1,17 @@ +from typing import List, Dict + +from ..core.model_interface import FridayLLM, LLMBackend + + +class ChatService: + """Minimal service wrapper for a Friday-style chat interface.""" + + def __init__(self, backend: LLMBackend) -> None: + self.llm = FridayLLM(backend) + self.history: List[Dict[str, str]] = [] + + def respond(self, message: str) -> str: + response = self.llm.chat(message, self.history) + self.history.append({"role": "user", "content": message}) + self.history.append({"role": "assistant", "content": response}) + return response