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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions modules/friday-core/README.md
Original file line number Diff line number Diff line change
@@ -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.
94 changes: 94 additions & 0 deletions modules/friday-core/src/llm/README.md
Original file line number Diff line number Diff line change
@@ -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.
19 changes: 19 additions & 0 deletions modules/friday-core/src/llm/agents/tool_router.py
Original file line number Diff line number Diff line change
@@ -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())
41 changes: 41 additions & 0 deletions modules/friday-core/src/llm/core/model_interface.py
Original file line number Diff line number Diff line change
@@ -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:"
17 changes: 17 additions & 0 deletions modules/friday-core/src/llm/inference/chat_service.py
Original file line number Diff line number Diff line change
@@ -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