Skip to content

Commit 23bbb6f

Browse files
author
Leo Louvar
committed
Release v7.1.0: Enhanced AI Playground
- Bump version to 7.1.0 - AI Playground: Chat mode with context (workflows, DBs, system, vectors) - AI Playground: Tasks (classify, extract entities, summarize, sentiment) - Context aggregator and Ollama integration - Document upload and hash-based embedding; semantic search in Vector UI - NL to SQL bridge (read-only, mock results) - RELEASE_NOTES_v7.1.0.md
1 parent 45fb057 commit 23bbb6f

11 files changed

Lines changed: 2359 additions & 136 deletions

File tree

RELEASE_NOTES_v7.1.0.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Zixir v7.1.0 — Enhanced AI Playground
2+
3+
Release 7.1 adds the **Enhanced AI Playground**: chat and task modes with integrated context (workflows, databases, system metrics, vectors), document upload and search, and natural language to SQL.
4+
5+
---
6+
7+
## New in 7.1
8+
9+
### AI Playground — Chat (primary interface)
10+
11+
- **Natural conversation** with your Ollama model (e.g. Llama 3.1)
12+
- **Context-aware responses** — the AI can see:
13+
- Active workflows and status
14+
- Database connections (sample data)
15+
- System metrics (uptime, memory)
16+
- Vector collections
17+
- **Quick action buttons** for common queries
18+
- **Conversation history** (per session, localStorage)
19+
- **Provider selection** (Ollama, OpenAI, etc.)
20+
21+
### AI Playground — Tasks
22+
23+
- **Classify Text** — categorize into custom labels
24+
- **Extract Entities** — names, dates, amounts
25+
- **Summarize** — condense to specified length
26+
- **Analyze Sentiment** — positive / negative / neutral
27+
All with your configured model, latency tracking, and JSON output.
28+
29+
### Integrated context (what the AI knows)
30+
31+
- **Workflows:** count, status, recent activity, success rates
32+
- **Databases:** configured connections, status, sample schema
33+
- **System:** Zixir version, uptime, memory, errors
34+
- **Vectors:** collection names, document counts
35+
36+
### Document upload & search
37+
38+
- **Upload files** (PDF, DOCX, TXT, MD, JSON) from the Vector Search UI
39+
- **Hash-based embeddings** (~1ms), no external API
40+
- **Semantic search** across uploaded documents (~2–4ms)
41+
- **Works offline**, zero extra dependencies
42+
43+
### Database query bridge
44+
45+
- **Natural language → SQL** conversion
46+
- **Read-only** query execution (safety enforced)
47+
- **SQL shown** in responses (mock/sample results in this release)
48+
49+
---
50+
51+
## Requirements
52+
53+
- **Elixir** 1.14+ / OTP 25+
54+
- **Zig** 0.15+ (build-time; `mix zig.get` after `mix deps.get`)
55+
- **Python** 3.8+ *(optional)* for ODBC and VectorDB
56+
- **Ollama** *(optional)* for local AI Playground chat
57+
58+
---
59+
60+
## Quick start
61+
62+
### First-time install
63+
64+
```bash
65+
git clone https://github.com/Zixir-lang/Zixir.git
66+
cd Zixir
67+
git checkout v7.1.0
68+
mix deps.get
69+
mix zig.get
70+
mix compile
71+
mix phx.server # start web UI
72+
```
73+
74+
Then open **http://localhost:4000**. Use **AI Playground** from the sidebar.
75+
76+
### Clean build (troubleshoot or reinstall)
77+
78+
```bash
79+
git clone https://github.com/Zixir-lang/Zixir.git
80+
cd Zixir
81+
git checkout -- .
82+
git fetch origin --tags
83+
git checkout v7.1.0
84+
mix clean
85+
mix deps.clean --all
86+
mix deps.get
87+
mix zig.get
88+
mix compile
89+
mix phx.server # start web UI
90+
```
91+
92+
Then open **http://localhost:4000** in your browser.
93+
94+
---
95+
96+
## License
97+
98+
**Apache-2.0** — see [LICENSE](LICENSE).

lib/zixir/context_aggregator.ex

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
defmodule Zixir.ContextAggregator do
2+
@moduledoc """
3+
Aggregates real-time context about workflows, databases, and system state
4+
for AI assistant consumption.
5+
6+
Provides a unified view of:
7+
- Active and recent workflows
8+
- Configured database connections and schemas
9+
- System metrics and performance data
10+
- Vector collection status
11+
- Recent logs and events
12+
13+
## Usage
14+
15+
context = Zixir.ContextAggregator.build_full_context()
16+
# Returns structured map with all system context
17+
18+
"""
19+
20+
alias Zixir.Cache
21+
require Logger
22+
23+
@doc """
24+
Build comprehensive context for AI assistant.
25+
"""
26+
@spec build_full_context() :: map()
27+
def build_full_context do
28+
%{
29+
workflows: get_workflows_context(),
30+
databases: get_databases_context(),
31+
system: get_system_metrics(),
32+
vectors: get_vector_context(),
33+
timestamp: DateTime.utc_now() |> DateTime.to_iso8601()
34+
}
35+
end
36+
37+
@doc """
38+
Get comprehensive workflow context.
39+
"""
40+
@spec get_workflows_context() :: map()
41+
def get_workflows_context do
42+
# Fetch from cache where workflows are stored
43+
workflows = fetch_all_workflows()
44+
45+
%{
46+
total: length(workflows),
47+
active: Enum.count(workflows, &(&1.status == "active")),
48+
paused: Enum.count(workflows, &(&1.status == "paused")),
49+
failed: Enum.count(workflows, &(&1.status == "failed")),
50+
completed: Enum.count(workflows, &(&1.status == "completed")),
51+
recent: get_recent_workflow_runs(workflows, 5),
52+
list: workflows |> Enum.take(10) |> Enum.map(&format_workflow/1)
53+
}
54+
end
55+
56+
@doc """
57+
Get database connections and schema context.
58+
"""
59+
@spec get_databases_context() :: map()
60+
def get_databases_context do
61+
connections = fetch_connections()
62+
63+
%{
64+
total: length(connections),
65+
connections: Enum.map(connections, fn conn ->
66+
%{
67+
id: conn.id,
68+
name: conn.name,
69+
type: conn.type,
70+
host: Map.get(conn, :host, "localhost"),
71+
status: Map.get(conn, :status, "unknown"),
72+
tables: fetch_table_list(conn.id)
73+
}
74+
end)
75+
}
76+
end
77+
78+
defp fetch_connections do
79+
# Try to get connections from cache
80+
case Cache.get("connections:all") do
81+
{:ok, connections} when is_list(connections) -> connections
82+
_ -> fetch_sample_connections()
83+
end
84+
end
85+
86+
defp fetch_sample_connections do
87+
# Return sample connections for demo/development
88+
[
89+
%{
90+
id: "conn_001",
91+
name: "SQL Server Production",
92+
type: "sqlserver",
93+
host: "localhost",
94+
status: "connected"
95+
},
96+
%{
97+
id: "conn_002",
98+
name: "PostgreSQL Analytics",
99+
type: "postgresql",
100+
host: "localhost",
101+
status: "connected"
102+
},
103+
%{
104+
id: "conn_003",
105+
name: "MySQL Legacy",
106+
type: "mysql",
107+
host: "localhost",
108+
status: "disconnected"
109+
}
110+
]
111+
end
112+
113+
@doc """
114+
Get system metrics and performance data.
115+
"""
116+
@spec get_system_metrics() :: map()
117+
def get_system_metrics do
118+
%{
119+
uptime_minutes: get_uptime(),
120+
memory_usage: get_memory_usage(),
121+
active_connections: get_active_connection_count(),
122+
queue_depth: get_queue_depth(),
123+
recent_errors: get_recent_errors(5),
124+
version: get_zixir_version()
125+
}
126+
end
127+
128+
@doc """
129+
Get vector database context.
130+
"""
131+
@spec get_vector_context() :: map()
132+
def get_vector_context do
133+
case Cache.get("vector:collections") do
134+
{:ok, collections} when is_list(collections) ->
135+
%{
136+
total_collections: length(collections),
137+
collections: Enum.map(collections, fn coll ->
138+
%{
139+
name: coll.name,
140+
dimensions: coll.dimensions || 1536,
141+
document_count: coll.document_count || 0,
142+
size_mb: coll.size_mb || 0
143+
}
144+
end)
145+
}
146+
_ ->
147+
%{
148+
total_collections: 0,
149+
collections: []
150+
}
151+
end
152+
end
153+
154+
# Private functions
155+
156+
defp fetch_all_workflows do
157+
# Try to get workflows from cache
158+
case Cache.get("workflows:all") do
159+
{:ok, workflows} when is_list(workflows) -> workflows
160+
_ -> fetch_workflows_from_storage()
161+
end
162+
end
163+
164+
defp fetch_workflows_from_storage do
165+
# Fallback: return sample/demo workflows if cache is empty
166+
# In production, this would query the database
167+
[
168+
%{
169+
id: "wf_001",
170+
name: "order_processing",
171+
status: "active",
172+
last_run: DateTime.utc_now() |> DateTime.add(-3600, :second),
173+
total_runs: 47,
174+
success_rate: 0.94
175+
},
176+
%{
177+
id: "wf_002",
178+
name: "data_sync",
179+
status: "paused",
180+
last_run: DateTime.utc_now() |> DateTime.add(-86400, :second),
181+
total_runs: 12,
182+
success_rate: 1.0
183+
},
184+
%{
185+
id: "wf_003",
186+
name: "report_generation",
187+
status: "completed",
188+
last_run: DateTime.utc_now() |> DateTime.add(-7200, :second),
189+
total_runs: 8,
190+
success_rate: 0.88
191+
}
192+
]
193+
end
194+
195+
defp get_recent_workflow_runs(workflows, limit) do
196+
workflows
197+
|> Enum.sort_by(& &1.last_run, {:desc, DateTime})
198+
|> Enum.take(limit)
199+
|> Enum.map(fn wf ->
200+
%{
201+
id: wf.id,
202+
name: wf.name,
203+
status: wf.status,
204+
time_ago: format_time_ago(wf.last_run)
205+
}
206+
end)
207+
end
208+
209+
defp format_workflow(wf) do
210+
%{
211+
id: wf.id,
212+
name: wf.name,
213+
status: wf.status,
214+
runs: wf.total_runs,
215+
success_rate: Float.round(wf.success_rate * 100, 1)
216+
}
217+
end
218+
219+
defp get_connection_status(conn_id) do
220+
case Cache.get("connection:#{conn_id}:status") do
221+
{:ok, status} -> status
222+
_ -> "unknown"
223+
end
224+
end
225+
226+
defp fetch_table_list(conn_id) do
227+
case Cache.get("connection:#{conn_id}:tables") do
228+
{:ok, tables} when is_list(tables) ->
229+
Enum.take(tables, 20)
230+
_ ->
231+
[]
232+
end
233+
end
234+
235+
defp get_uptime do
236+
# Get system uptime in minutes
237+
case :erlang.statistics(:wall_clock) do
238+
{ms, _} -> div(ms, 60000)
239+
_ -> 0
240+
end
241+
end
242+
243+
defp get_memory_usage do
244+
# Get memory usage in MB
245+
case :erlang.memory(:total) do
246+
bytes -> div(bytes, 1024 * 1024)
247+
_ -> 0
248+
end
249+
end
250+
251+
defp get_active_connection_count do
252+
# Count active WebSocket/HTTP connections
253+
# This is a simplified version
254+
3
255+
end
256+
257+
defp get_queue_depth do
258+
# Get job queue depth
259+
case Cache.get("queue:depth") do
260+
{:ok, depth} when is_integer(depth) -> depth
261+
_ -> 0
262+
end
263+
end
264+
265+
defp get_recent_errors(limit) do
266+
# Fetch recent errors from cache/logs
267+
case Cache.get("logs:errors:recent") do
268+
{:ok, errors} when is_list(errors) ->
269+
Enum.take(errors, limit)
270+
_ ->
271+
[]
272+
end
273+
end
274+
275+
defp get_zixir_version do
276+
# Get version from application
277+
case Application.spec(:zixir, :vsn) do
278+
vsn when is_list(vsn) -> List.to_string(vsn)
279+
_ -> "7.0.0"
280+
end
281+
end
282+
283+
defp format_time_ago(datetime) do
284+
now = DateTime.utc_now()
285+
diff = DateTime.diff(now, datetime, :second)
286+
287+
cond do
288+
diff < 60 -> "#{diff}s ago"
289+
diff < 3600 -> "#{div(diff, 60)}m ago"
290+
diff < 86400 -> "#{div(diff, 3600)}h ago"
291+
true -> "#{div(diff, 86400)}d ago"
292+
end
293+
end
294+
end

0 commit comments

Comments
 (0)