Historical case · August 2024
Violet
A personal AI assistant prototype that connected model output to controlled local actions: command execution, browser automation, persistent conversational state and iterative tool-result feedback.
Why I built it
I was interested in AI as an interface to software, not only as a chat surface. The core question was whether a model could interpret intent, choose an action, execute it through constrained local capabilities, inspect the result and continue without receiving unrestricted control of the machine.
Violet was built before MCP became a standard. I do not claim it invented MCP or modern tool calling; the interesting part is that I independently converged on several of the same systems problems: tool boundaries, execution feedback, persistent state and approval around side effects.
What it could do
- Persistent memory: conversation history stored in SQLite and reloaded across sessions.
- Local command execution: model output could request Windows terminal commands through a controlled protocol.
- Approval gate: the user was asked before an allowed command was actually executed.
- Result interpretation: command output was sent back to the model so it could continue reasoning about the task.
- Sequential actions: the execution loop could continue when another valid action followed a tool result.
- Browser control: Selenium opened pages, searched fields and interacted with DOM elements from model-issued instructions.
Evidence from 2024
These are preserved screenshots from the original development period. I prefer showing them because they make the timeline concrete instead of asking the reader to trust a retrospective description.
Timeline context. The dated screenshots and contemporary post anchor these capabilities to the original 2024 development period, rather than relying on a retrospective description written today.
Architecture
User request
↓
Language model
↓
Action protocol
├── normal response
├── local command request
└── browser action
↓
Validation / human approval
↓
Execution layer
├── subprocess
└── Selenium
↓
Observed result
↓
Persist history + feed result back to model
↓
Continue or return to user
The implementation used textual action delimiters. It worked as an experiment, but it is one of the clearest limitations of the prototype: modern structured tool calling is safer and less brittle than parsing free-form model text.
Safety and operational boundaries
Violet was never intended to have unrestricted machine authority. Command execution passed through validation and the user was prompted before execution. The browser layer operated through ordinary Selenium controls rather than hidden system access.
What I would change today
- Replace delimiter parsing with typed tool schemas and explicit arguments.
- Use capability-scoped tools instead of generic shell access wherever possible.
- Add durable execution traces, correlation IDs and normalized failure states.
- Separate model planning, tool authorization and execution into independent boundaries.
- Use stronger browser state validation instead of assuming a successful Selenium call proves the intended outcome.
- Add regression tests and policy checks around every side-effecting capability.
Why it still matters
Violet changed the way I think about AI systems. I stopped treating the model as the product and started treating it as one component inside a larger engineered workflow. That same idea now appears in how I use coding agents: explicit context, bounded authority, observable actions, validation, checkpoints and evidence before completion.