Skip to content

Commit e249c5c

Browse files
committed
feat(hub): fetch models + vision override, endpoint editor redesign, legible Lua results (v6.2.0)
AI Settings: Fetch models (GET /v1/models) for the HTTP backend and endpoint editor; Vision Auto/On/Off override so a multimodal model the name heuristic misses can force-enable the camera/vision gate. API-profiles endpoint editor redesign: visibility fix (HTTP no longer shows LLMUnity fields), Advanced foldout, placeholder hints, LLMUnity GGUF dropdown, empty context window = no limit, endpoint list with per-row Remove. Lua result legibility: execute_lua trims null Error / nil Output, and table returns serialise to JSON so coreai_world_list_prefabs()/coreai_world_find() are readable instead of 'table: 0x...'. Programmer prompt: MoonSharp -> Lua sandbox (runtime migrated to Lua-CSharp).
1 parent ebc9da8 commit e249c5c

13 files changed

Lines changed: 722 additions & 141 deletions

File tree

Assets/CoreAI/CHANGELOG.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
11
# Changelog
22

3+
## [6.2.0] - 2026-07-23
4+
5+
### Added
6+
7+
- Hub **AI Settings → Fetch models** (HTTP backend and endpoint editor): queries an OpenAI-compatible
8+
`GET {baseUrl}/models` and lists the advertised model ids in a dropdown, so an exact name can be
9+
copied into the model field instead of typed from memory. (`CoreAiBackend.ListModelsAsync`)
10+
- Hub **AI Settings → Vision** override (Auto / On / Off): forces the vision/camera gate on a multimodal
11+
model whose name the auto-heuristic does not recognise (e.g. a local `qwen3.5` vision build), so the
12+
camera tool and image sends become usable without renaming the model. (`CoreAISettingsAsset.SetVisionSupport`)
13+
14+
### Changed
15+
16+
- Hub **API-profiles endpoint editor** redesigned: field visibility is applied on first render (HTTP
17+
endpoints no longer show LLMUnity-only fields), an **Advanced** foldout hides secondary fields
18+
(Endpoint ID, context window, ports, slots, secret reference, LLMUnity options), text fields carry
19+
placeholder hints, LLMUnity endpoints pick their model from a **GGUF dropdown**, an empty context
20+
window now means **no limit**, and endpoints are managed through a **list with a per-row Remove**
21+
instead of a picker plus one ambiguous Remove button.
22+
- `execute_lua` result envelope is trimmed for the model: a null `Error` and an empty/`nil` `Output`
23+
are dropped, so a side-effect success serialises to `{"Success":true}` rather than
24+
`{"Success":true,"Output":"nil","Error":null}`.
25+
- `execute_lua` **table return values now serialise to JSON**: `return coreai_world_list_prefabs()` /
26+
`coreai_world_find(...)` hand the model `["cube","sphere",...]` instead of an opaque `table: 0x…`
27+
address, so discovery tools are actually legible.
28+
- Programmer system prompt: "CoreAI MoonSharp sandbox" → "CoreAI Lua sandbox" (the persistent mod
29+
runtime migrated to Lua-CSharp; MoonSharp is no longer instantiated in production).
30+
331
## [6.1.3] - 2026-07-23
432

533
### Changed

Assets/CoreAI/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.neoxider.coreai",
3-
"version": "6.1.3",
3+
"version": "6.2.0",
44
"displayName": "CoreAI",
55
"unity": "6000.0",
66
"description": "Portable C# core for CoreAI \u2014 LLM agents that call your game code. Orchestration, function-calling tools, agent memory, AgentBuilder, SkillSet, and production resilience (retries, timeouts, rate limits), with no UnityEngine dependency. LLM and Lua are optional modules (COREAI_NO_LLM / COREAI_NO_LUA), so the core compiles without them \u2014 install only what your game uses. Unity integration ships in com.neoxider.coreaiunity.",

Assets/CoreAIBenchmark/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.neoxider.coreaibenchmark",
3-
"version": "6.1.3",
3+
"version": "6.2.0",
44
"displayName": "CoreAI Benchmark",
55
"unity": "6000.0",
66
"description": "LLM game-creation benchmark harness and scenarios for CoreAI: drives execute_lua and world_command through real PlayMode scenarios (G1-G8), grades tool correctness, reasoning, instruction adherence, and determinism, and reports suite/role fitness scores. Depends on com.neoxider.coreai / com.neoxider.coreaiunity / com.neoxider.coreaimods.",

Assets/CoreAIHub/Runtime/HubSettingsPage.cs

Lines changed: 479 additions & 133 deletions
Large diffs are not rendered by default.

Assets/CoreAIHub/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.neoxider.coreaihub",
3-
"version": "6.1.3",
3+
"version": "6.2.0",
44
"displayName": "CoreAI Hub (UI Toolkit)",
55
"unity": "6000.0",
66
"description": "Optional UI Toolkit window for CoreAI: a tabbed Hub that renders pages registered into CoreAI's HubPageRegistry (Chat, Settings, Statistics, Mods, and C#/Lua-authored pages). Lazy per-tab content, live tab rebuild on register/unregister, semi-transparent runtime panel, and a future path to Unity 6.5 world-space PanelRenderer. Install this package only when you want the built-in Hub window; without it CoreAI still exposes the registry so you can render pages on your own uGUI/UITK canvas via the API. Depends on com.neoxider.coreai.",

Assets/CoreAIMcp/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.neoxider.coreaimcp",
3-
"version": "6.1.3",
3+
"version": "6.2.0",
44
"displayName": "CoreAI MCP Server",
55
"unity": "6000.0",
66
"description": "Optional Model Context Protocol (MCP) server that runs INSIDE a live CoreAI game session (play mode or a build) so an external agent - Claude Code and any other MCP client - can drive the running game over a standard protocol. Exposes the in-game Command Bar surface (execute_lua, manage_mods, get_mod_logs, and, when present, world_command + screenshot) as MCP tools over localhost streamable HTTP. Off by default: drop a CoreAiMcpServer component into a scene (or call CoreAiMcpServer.StartServer). Localhost-only, opt-in, no auth - never expose beyond loopback. Depends on com.neoxider.coreaimods; world/screenshot tools register only when those services exist in the current composition.",

Assets/CoreAIMods/Runtime/Infrastructure/LuaCsGameToolExecutor.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ internal static string Summarize(object[] results)
142142
return Stringify(results[0]);
143143
}
144144

145+
/// <summary>Max table nesting rendered into the Output summary before values are elided.</summary>
146+
private const int MaxTableSummaryDepth = 4;
147+
145148
private static string Stringify(object value)
146149
{
147150
IValueMarshaller marshaller = LuaCsValueMarshaller.Instance;
@@ -155,11 +158,30 @@ private static string Stringify(object value)
155158
return ((double)marshaller.ToHostValue(value)).ToString(CultureInfo.InvariantCulture);
156159
case ScriptValueKind.String:
157160
return (string)marshaller.ToHostValue(value) ?? "";
161+
case ScriptValueKind.Table:
162+
return StringifyTable(marshaller, value);
158163
default:
159164
return marshaller.Describe(value);
160165
}
161166
}
162167

168+
// WHY: a returned table otherwise renders as "table: 0x…" (its address), which is useless to the
169+
// model — e.g. `return coreai_world_list_prefabs()` or `coreai_world_find(...)` would hand the LLM
170+
// an opaque handle instead of the actual names. Convert it to a portable structure and JSON-encode
171+
// it so discovery tools are legible; fall back to the plain describe if conversion/encoding fails.
172+
private static string StringifyTable(IValueMarshaller marshaller, object value)
173+
{
174+
try
175+
{
176+
object portable = marshaller.ToPortable(value, MaxTableSummaryDepth);
177+
return Newtonsoft.Json.JsonConvert.SerializeObject(portable);
178+
}
179+
catch (Exception)
180+
{
181+
return marshaller.Describe(value);
182+
}
183+
}
184+
163185
private static string Truncate(string value, int maxLength)
164186
{
165187
if (string.IsNullOrEmpty(value) || value.Length <= maxLength)

Assets/CoreAIMods/Runtime/LuaExecution/LuaTool.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,31 @@ public async Task<string> ExecuteAsync(
131131
}
132132
}
133133

134+
private static readonly JsonSerializerSettings TrimNulls = new()
135+
{
136+
NullValueHandling = NullValueHandling.Ignore
137+
};
138+
134139
private static string SerializeResult(LuaResult result)
135140
{
136-
return JsonConvert.SerializeObject(result);
141+
// WHY: trim boilerplate the model does not need — an empty/`nil` Output and a null Error are
142+
// pure noise on success. A successful side-effect call serialises to {"Success":true}; a real
143+
// return value or a failure Error still rides along. Keeps weak local models from reasoning over
144+
// "Output":"nil" / "Error":null on every tool result.
145+
string output = result.Output;
146+
if (string.IsNullOrEmpty(output) || string.Equals(output, "nil", StringComparison.Ordinal))
147+
{
148+
output = null;
149+
}
150+
151+
return JsonConvert.SerializeObject(
152+
new LuaResult
153+
{
154+
Success = result.Success,
155+
Output = output,
156+
Error = string.IsNullOrEmpty(result.Error) ? null : result.Error
157+
},
158+
TrimNulls);
137159
}
138160

139161
/// <summary>Lua execution outcome for JSON serialization back to the model.</summary>

Assets/CoreAIMods/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.neoxider.coreaimods",
3-
"version": "6.1.3",
3+
"version": "6.2.0",
44
"displayName": "CoreAI Mods (Lua)",
55
"unity": "6000.0",
66
"description": "Lua modding layer for CoreAI: the Lua-CSharp sandbox (managed, AOT-safe, WebGL/IL2CPP-ready — bundled, no external package), execute_lua and manage_mods tools, the Lua Modding skill, the mod runtime, persistent mod stores, gameplay bindings, and mod UI. Depends on com.neoxider.coreai / com.neoxider.coreaiunity. Install this package only when you want AI/player-authored Lua mods; without it CoreAI compiles Lua-free.",

Assets/CoreAiUnity/Resources/AgentPrompts/System/Programmer.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
You are the Programmer agent for CoreAI MoonSharp sandbox.
1+
You are the Programmer agent for the CoreAI Lua sandbox.
22
Use the execute_lua tool for one-shot Lua and manage_mods (list/get_source/load/reload/unload) for persistent mods with hooks or timers.
33
Before writing any non-trivial mod (a game loop, cross-mod communication, input handling), call read_skill('Lua Modding') once - it returns the full API reference with worked examples; this prompt carries only the survival minimum. For Roblox-style scripts (Instance.new, game/workspace, Vector3/CFrame/Color3, Part properties), call read_skill('Rbx API') instead.
44
Use only real Lua globals exposed by the host. Baseline globals include report(message) and add(a,b). Do not use print(), io, os, require, load, loadfile, dofile, debug, game.enemies, game.create, GameObject.Find, or invented APIs.

0 commit comments

Comments
 (0)