You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Assets/CoreAI/Docs/LLM_ROUTING.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -43,5 +43,6 @@ Production games such as RedoSchool should put provider keys and quota enforceme
43
43
44
44
-**Orchestrator / chat window:**`ICoreAISettings.LlmRequestTimeoutSeconds` is enforced by `CoreAiChatService` (`CancelAfterSlim`, WebGL-safe) for both streaming and non-streaming chat calls.
45
45
-**HTTP per request:**`IOpenAiHttpSettings.RequestTimeoutSeconds` caps a single `MeaiOpenAiChatClient` round-trip. On Unity, `CoreAISettingsAsset.EffectiveHttpRequestTimeoutSeconds` applies `min(RequestTimeoutSeconds, ceil(LlmRequestTimeoutSeconds))` so the transport does not outlive the orchestrator cancel window (see [`MEAI_TOKENS_FACT_VS_ESTIMATE.md`](MEAI_TOKENS_FACT_VS_ESTIMATE.md), §3).
46
-
-**Typed timeout vs cancel:** When only the library timeout fires, callers may receive `LlmOperationTimeoutException`. `RoutingLlmClient` publishes `LlmRequestCompleted` with `LlmErrorCode.Timeout` vs `Cancelled` for non-streaming failures; streaming may still surface a terminal `LlmStreamChunk` with `Error = "cancelled"` when lower layers normalize cancellation (see [`MEAI_TOKENS_FACT_VS_ESTIMATE.md`](MEAI_TOKENS_FACT_VS_ESTIMATE.md), §4).
46
+
-**Typed timeout vs cancel:** When only the library timeout fires, callers may receive `LlmOperationTimeoutException`. `RoutingLlmClient` publishes `LlmRequestCompleted` with `LlmErrorCode.Timeout` vs `Cancelled`. Transport/internal timeouts — including a header phase that never completes and the timeout decorator's own linked token — surface as typed `Timeout` on both streaming and non-streaming paths; `Cancelled` is reported only when the caller actually cancelled, so timeouts stay retry/fallback-eligible (see [`MEAI_TOKENS_FACT_VS_ESTIMATE.md`](MEAI_TOKENS_FACT_VS_ESTIMATE.md), §4).
47
+
-**Retry/fallback replay guard:** a failed completion that carries evidence of an **executed** tool call is not replayed by the HTTP retry loop or the fallback chain — the failure propagates instead of re-mutating the world. Rejected tool calls (duplicate-suppressed, parse errors, unknown tool names, schema/argument-conversion failures) are treated as never-invoked and do not block retries or fallback.
47
48
-**Usage accounting:**`LlmUsageRecord` / `ILlmUsageSink` and `LlmUsageReported` (MessagePipe) complement routing; token counts from HTTP usage are described in [`MEAI_TOKENS_FACT_VS_ESTIMATE.md`](MEAI_TOKENS_FACT_VS_ESTIMATE.md).
Copy file name to clipboardExpand all lines: Assets/CoreAI/Docs/MEAI_TOKENS_FACT_VS_ESTIMATE.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -31,6 +31,8 @@ OpenAI-style servers may emit a **final** SSE object with an empty `choices` arr
31
31
32
32
If the provider does not send `usage` while streaming, facts may exist only on the non-streaming path—or not at all, depending on the server.
33
33
34
+
**Multi-roundtrip (tool-calling) turns:** usage on the terminal result is **cumulative across the whole turn** — streaming usage is summed over every tool roundtrip, and `PromptTokens + CompletionTokens == TotalTokens` holds for cost/usage consumers. The width of the context actually sent on the **final roundtrip** is reported separately as `LastRoundtripPromptTokens` (used for prompt-size calibration; providers that emit zero usage cannot pollute it).
35
+
34
36
---
35
37
36
38
## 3. Two timeouts: orchestrator and HTTP
@@ -51,7 +53,7 @@ so a single HTTP call **cannot outlive** the orchestrator cancel (important for
51
53
- If **only** the chat timeout token fires (`timeoutCts`) and the **outer** user `ct` is **not** cancelled, `CoreAiChatService` throws **`LlmOperationTimeoutException`** (subclass of `OperationCanceledException`) to distinguish library timeout from explicit user cancel.
52
54
-**`RoutingLlmClient`** maps non-streaming failures to `LlmRequestCompleted` with **`LlmErrorCode.Timeout`** vs **`Cancelled`** based on exception type.
53
55
54
-
**Streaming:**decorators such as `LoggingLlmClientDecorator` may normalize cancel/timeout into a **terminal**`LlmStreamChunk` with an error field like **`"cancelled"`**. Then **`LlmErrorCode.Timeout` on `LlmRequestCompleted` for streaming is not guaranteed** end-to-end unless `LlmOperationTimeoutException` propagates through every layer. For UI, see patterns like `ResolveTimeoutMessage` on `CoreAiChatPanel` (empty message = do not duplicate a system line).
56
+
**Transport/internal timeouts are typed `Timeout`, never `Cancelled`:**a transport-internal timeout (e.g. a backend that never sends response headers) or the timeout decorator's own linked token firing surfaces as a typed timeout on **both**the streaming and non-streaming paths — an inner `Cancelled` result/terminal chunk caused by the decorator's timeout is reclassified to `Timeout`, and `TimeoutException` maps to `LlmErrorCode.Timeout`. `Cancelled` is reported **only when the caller's own token was cancelled**, so timeouts stay retry/fallback-eligible while explicit user cancels are never retried. For UI, see patterns like `ResolveTimeoutMessage` on `CoreAiChatPanel` (empty message = do not duplicate a system line).
Copy file name to clipboardExpand all lines: Assets/CoreAIBenchmark/README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -88,7 +88,7 @@ The window has four tabs, plus toolbar **Open folder** / **Open report** shortcu
88
88
89
89
| Tab | Purpose |
90
90
|---|---|
91
-
| Run | Choose model/base URL overrides, scenario groups (G1-G8), repetitions, retries, timeout override, and start a run. |
91
+
| Run | Choose model/base URL overrides, scenario groups (G1-G8), repetitions, retries, timeout override, and start a run. While a run is active a **Stop (save partial)** button appears: it takes effect at retry boundaries (no waiting out every timeout attempt), saves a partial report, and stop-aborted attempts are never scored as model failures. |
92
92
| History | Browse past runs grouped by model, inspect dimension/role scores, open reports, and view captured scene thumbnails. |
93
93
| Models | A sortable leaderboard of the newest run per model, ranked by suite score, speed, pass-rate, or game-fit. |
94
94
| Compare | Select the newest JSON reports per model, optionally pin one model first, and build `COMPARISON.md` plus `COMPARISON.svg`. |
Copy file name to clipboardExpand all lines: Assets/CoreAiUnity/Docs/ARCHITECTURE.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -74,7 +74,7 @@ If the game adds a **child** `LifetimeScope` (VContainer parent = `CoreAILifetim
74
74
75
75
`IAiPromptContextProvider` lets a game append per-request context such as current quest, lesson slot, learner profile, or world objective without mutating the static role prompt. `AiPromptComposer` appends these sections under `## Runtime Context`.
76
76
77
-
`ScopedAgentMemoryStoreDecorator` and `IAgentMemoryScopeProvider` let projects isolate memory by tenant, user, session, topic, and role while preserving the old role-only key when no scope provider is registered.
77
+
`ScopedAgentMemoryStoreDecorator` and `IAgentMemoryScopeProvider` let projects isolate memory by tenant, user, session, topic, and role while preserving the old role-only key when no scope provider is registered. Lossless scope ids (including GUIDs) keep their legacy on-disk keys; a lossy id (one that sanitization would alter, or that mimics the hashed shape) gets a raw-length prefix plus a `-<12 hex>` hash suffix of the trimmed id, so distinct raw scopes can never collide into the same memory bucket.
78
78
79
79
`IConversationContextManager` prepares long chat history before each LLM call. The default `DeterministicConversationContextManager` keeps recent messages in `ChatHistory` and compacts older turns into a `## Conversation Summary` system section using `IConversationSummaryStore`. **`RegisterCorePortable`** registers **`InMemoryConversationSummaryStore`** by default so summaries accumulate across turns for each role for the process lifetime. **`IContextBudgetPolicy`** (`DefaultContextBudgetPolicy`) plus **`ITokenEstimator`** (`HeuristicTokenEstimator`) allocate a **`HistoryTokenBudget`** from the role/context window minus reserved completion headroom and an estimate of system + user + tool-contract text — this replaces the legacy fixed `ContextTokens/2` split.
Copy file name to clipboardExpand all lines: Assets/CoreAiUnity/Docs/COREAI_SETTINGS.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -257,7 +257,7 @@ These fields live in the **Advanced** inspector under **Chat history summarizati
257
257
|------|-------------|----------|
258
258
|**Enable history summarization**| ✅ | When off, the full loaded chat transcript is kept in the MEAI tail without rolling older turns into `## Conversation Summary` (may exceed the model context). |
259
259
|**Recent history token budget override**|`0`|`0` = automatic from context window minus system/tools/user (via `DefaultContextBudgetPolicy`). When set to a positive value, caps the verbatim tail to that many **estimated** tokens; older lines fold into the rolling summary when summarization is on (minimum applied: 32). |
260
-
|**Max rolled summary (tokens)**|`0`|`0` = no extra cap. When set, truncates the persisted rolling summary to roughly that many estimated tokens after each rollup (deterministic bullet path and LLM-assisted path). |
260
+
|**Max rolled summary (tokens)**|`2048`|`0` = unlimited (no cap). When set, truncates the persisted rolling summary to roughly that many estimated tokens after each rollup (deterministic bullet path and LLM-assisted path), keeping the newest content and evicting the oldest. `2048` is the default only for fresh installs. |
261
261
|**Compaction trigger ratio**|`0.8`| Roadmap §2. Compaction checks estimated history tokens against `historyBudget * ratio`; below the trigger, all turns stay verbatim and the stored summary is not rewritten. Invalid values fall back to the CoreAI default threshold. |
262
262
|**Enable context pruning**| ✅ | Roadmap §7 context editing. Before summarization, prunes only the in-memory prompt history copy: exact consecutive duplicates are collapsed and stale `tool` / `## Tool Results` observations are omitted. Durable stored chat history is unchanged. |
263
263
|**Max retained tool results**|`3`| Newest durable `tool` / `## Tool Results` messages retained in the prompt history copy before compaction. Older tool observations are treated as superseded by newer turns. |
Without extra setup, **`RegisterCorePortable()`** wires **`InMemoryConversationSummaryStore`**: older turns that no longer fit the token budget become a deterministic **`## Conversation Summary`** block, and summaries **accumulate in memory per role** for the app process.
424
424
425
+
The **stored** summary's final line is a `[fold:v1:<hashes>]` fold marker (content hashes of the last folded messages) that records how far history has already been folded. It is internal bookkeeping: it is stamped after the token cap (so the limiter can never trim it) and stripped from every LLM- and UI-facing view of the summary.
426
+
425
427
Unity scenes using **`CoreAILifetimeScope`** switch to **`FileConversationSummaryStore`** under **`%persistentDataPath%/CoreAI/ConversationSummaries`** so compaction survives restarts, then **`RegisterCorePortable(suppressDefaultConversationSummaryStore: true, suppressDefaultAgentMemoryStore: true)`** (**v1.5.22** adds agent-memory suppression so **`IAgentMemoryStore`** is not double-registered).
426
428
427
429
This is separate from **`FileAgentMemoryStore`** transcript JSON; orchestration details are in [ARCHITECTURE.md](ARCHITECTURE.md) and [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md).
Copy file name to clipboardExpand all lines: Assets/CoreAiUnity/Docs/MemorySystem.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -44,6 +44,8 @@ Granular edits operate on the canonical `AgentMemoryState.Memory` document that
44
44
45
45
Every successful memory mutation records a bounded audit snapshot on `AgentMemoryState.Versions`: version number, UTC timestamp, action, full `contentAfter`, and a short size-delta note. Stores that preserve the full `AgentMemoryState` retain those snapshots; custom stores can persist them alongside `Memory`. Use `IAgentMemoryStore.ListVersions(roleId)` to inspect retained snapshots and `IAgentMemoryStore.Revert(roleId, version)` to restore one; revert itself creates a new version.
46
46
47
+
Two levels of "clear": the model-facing `memory(action=clear)` wipes only the memory **document** — the wipe is versioned and revertible, and chat history/transcripts survive, so the model cannot erase the user's conversation record. The store-level `IAgentMemoryStore.Clear(roleId)` is a full reset: it also wipes the version history and the system-prompt snapshot, so cleared memory can never be re-injected into system prompts.
Copy file name to clipboardExpand all lines: Assets/CoreAiUnity/Docs/WORLD_COMMANDS.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -207,7 +207,7 @@ Net effect: a mod that re-spawns "its" objects on load never races the snapshot
207
207
|`px, py, pz`| World position |
208
208
|`rx, ry, rz`| Euler rotation |
209
209
|`sx, sy, sz`| Local scale |
210
-
|`parent`| Parent object name (empty if root) |
210
+
|`parent`| Parent object name (empty if root). A child whose parent's prefab is currently unresolved keeps its remembered parent id across autosaves until the prefab returns (it is not re-saved as a root orphan); an explicit `parent: none` detach or reparent clears the remembered link, so the old parent is not resurrected.|
211
211
|`active`| Whether the object is enabled |
212
212
|`cr, cg, cb, ca`|**Optional** — only present if `set_color` was called on the object; otherwise `-1` (sentinel). Prefabs without explicit `set_color` keep their original material. |
0 commit comments