arcane-os 0.1.0-dev.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/COMMERCIAL-LICENSE.md +13 -0
  3. package/LICENSE +661 -0
  4. package/NOTICE +70 -0
  5. package/README.md +448 -0
  6. package/bin/arcane-test.mjs +741 -0
  7. package/bin/arcane.mjs +5 -0
  8. package/docs/architecture.md +234 -0
  9. package/docs/compatibility.md +36 -0
  10. package/docs/event-manager.md +166 -0
  11. package/docs/platform-targets.md +108 -0
  12. package/docs/publishing.md +203 -0
  13. package/docs/reference/README.md +117 -0
  14. package/docs/reference/arcane-ollama.md +288 -0
  15. package/docs/reference/availability-and-normalization.md +123 -0
  16. package/docs/reference/behavioral-testing.md +86 -0
  17. package/docs/reference/cli.md +569 -0
  18. package/docs/reference/core/README.md +62 -0
  19. package/docs/reference/core/arcane-ai-contracts.md +873 -0
  20. package/docs/reference/core/arcane-api.md +601 -0
  21. package/docs/reference/core/arcane-entities.md +65 -0
  22. package/docs/reference/core/arcane-events.md +134 -0
  23. package/docs/reference/core/ollama-module.md +181 -0
  24. package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +1909 -0
  25. package/docs/reference/core/reference/arcane-api/applications-terminal-capabilities.md +1057 -0
  26. package/docs/reference/core/reference/arcane-api/core-and-events.md +320 -0
  27. package/docs/reference/core/reference/arcane-api/filesystem-storage-preferences-appearance.md +610 -0
  28. package/docs/reference/core/reference/arcane-api/namespaces.md +1157 -0
  29. package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +1423 -0
  30. package/docs/reference/core/reference/arcane-api/session-provisioning-diagnostics-development.md +315 -0
  31. package/docs/reference/event-manager.md +957 -0
  32. package/docs/reference/inventory/package-api.json +2632 -0
  33. package/docs/reference/inventory/runtime-components.json +934 -0
  34. package/docs/reference/inventory/runtime-entities.json +26 -0
  35. package/docs/reference/inventory/runtime-modules.json +1249 -0
  36. package/docs/reference/protocols.md +242 -0
  37. package/docs/reference/runtime-components.md +1098 -0
  38. package/docs/reference/runtime-entities.md +303 -0
  39. package/docs/reference/runtime-modules.md +2010 -0
  40. package/docs/reference/sdk-api.md +4901 -0
  41. package/docs/roadmap.md +79 -0
  42. package/docs/work-amplification.md +124 -0
  43. package/node_modules/event-pubsub/CHANGELOG.md +55 -0
  44. package/node_modules/event-pubsub/MIGRATION.md +70 -0
  45. package/node_modules/event-pubsub/README.md +363 -0
  46. package/node_modules/event-pubsub/SECURITY.md +37 -0
  47. package/node_modules/event-pubsub/index.js +141 -0
  48. package/node_modules/event-pubsub/licence +21 -0
  49. package/node_modules/event-pubsub/package.json +59 -0
  50. package/node_modules/strong-type/README.md +408 -0
  51. package/node_modules/strong-type/assets/strong-type-header.png +0 -0
  52. package/node_modules/strong-type/index.js +1151 -0
  53. package/node_modules/strong-type/licence +21 -0
  54. package/node_modules/strong-type/node.js +125 -0
  55. package/node_modules/strong-type/package.json +61 -0
  56. package/package.json +95 -0
  57. package/runtime/ARCANE_RUNTIME_RELEASE.json +791 -0
  58. package/runtime/arcane/components/app-bar.html +468 -0
  59. package/runtime/arcane/components/assistant-panel.html +715 -0
  60. package/runtime/arcane/components/calculator.html +8 -0
  61. package/runtime/arcane/components/chart.html +655 -0
  62. package/runtime/arcane/components/chat.html +1225 -0
  63. package/runtime/arcane/components/conversation-view.html +13 -0
  64. package/runtime/arcane/components/dashboard-config.html +341 -0
  65. package/runtime/arcane/components/data-maintenance.html +112 -0
  66. package/runtime/arcane/components/data-view.html +92 -0
  67. package/runtime/arcane/components/directory-picker.html +197 -0
  68. package/runtime/arcane/components/document-inspector.html +252 -0
  69. package/runtime/arcane/components/file-drop.html +264 -0
  70. package/runtime/arcane/components/file-inspector.html +293 -0
  71. package/runtime/arcane/components/file-manager.html +1715 -0
  72. package/runtime/arcane/components/header.html +142 -0
  73. package/runtime/arcane/components/integration-settings.html +14 -0
  74. package/runtime/arcane/components/local-ai-status.html +360 -0
  75. package/runtime/arcane/components/markdown-document.html +1048 -0
  76. package/runtime/arcane/components/markdown-editor.html +360 -0
  77. package/runtime/arcane/components/media-embed.html +8 -0
  78. package/runtime/arcane/components/modal.html +402 -0
  79. package/runtime/arcane/components/output-panel.html +259 -0
  80. package/runtime/arcane/components/preferences-form.html +135 -0
  81. package/runtime/arcane/components/record-timeline.html +105 -0
  82. package/runtime/arcane/components/relationship-board.html +116 -0
  83. package/runtime/arcane/components/screen-capture.html +8 -0
  84. package/runtime/arcane/components/source-code-viewer.html +441 -0
  85. package/runtime/arcane/components/source-explanation.html +124 -0
  86. package/runtime/arcane/components/speech.html +365 -0
  87. package/runtime/arcane/components/summary-strip.html +177 -0
  88. package/runtime/arcane/components/table.html +77 -0
  89. package/runtime/arcane/components/task-progress.html +282 -0
  90. package/runtime/arcane/components/terminal-workspace.html +65 -0
  91. package/runtime/arcane/components/theme-editor.html +41 -0
  92. package/runtime/arcane/components/theme-switcher.html +46 -0
  93. package/runtime/arcane/components/unified-inbox.html +20 -0
  94. package/runtime/arcane/components/voice-transcription.html +476 -0
  95. package/runtime/arcane/components/weather-widget.html +8 -0
  96. package/runtime/arcane/components/web-navigator.html +239 -0
  97. package/runtime/arcane/css/communications.css +1 -0
  98. package/runtime/arcane/css/dashboard-config.css +45 -0
  99. package/runtime/arcane/css/document-site.css +981 -0
  100. package/runtime/arcane/css/layout.css +438 -0
  101. package/runtime/arcane/css/primitives.css +321 -0
  102. package/runtime/arcane/css/theme.css +112 -0
  103. package/runtime/arcane/css/utility-workspace.css +1 -0
  104. package/runtime/arcane/entities/ApiModelRecord.js +20 -0
  105. package/runtime/arcane/entities/Calculation.js +13 -0
  106. package/runtime/arcane/entities/Chat.js +581 -0
  107. package/runtime/arcane/entities/CommunicationMessage.js +29 -0
  108. package/runtime/arcane/entities/CommunicationThread.js +21 -0
  109. package/runtime/arcane/entities/Document.js +10 -0
  110. package/runtime/arcane/entities/File.js +143 -0
  111. package/runtime/arcane/entities/Image.js +135 -0
  112. package/runtime/arcane/entities/IntentEnvelope.js +834 -0
  113. package/runtime/arcane/entities/Preference.js +83 -0
  114. package/runtime/arcane/entities/TWiNPolicyDecision.js +1092 -0
  115. package/runtime/arcane/entities/TerminalSession.js +46 -0
  116. package/runtime/arcane/entities/Theme.js +107 -0
  117. package/runtime/arcane/entities/User.js +1046 -0
  118. package/runtime/arcane/entities/Weather.js +23 -0
  119. package/runtime/arcane/img/arcane-os-everywhere.png +0 -0
  120. package/runtime/arcane/img/arrow-left.png +0 -0
  121. package/runtime/arcane/img/arrow-right.png +0 -0
  122. package/runtime/arcane/img/doc.svg +5 -0
  123. package/runtime/arcane/img/folder.svg +4 -0
  124. package/runtime/arcane/img/image.svg +5 -0
  125. package/runtime/arcane/img/refresh.png +0 -0
  126. package/runtime/arcane/img/send.svg +9 -0
  127. package/runtime/arcane/img/trash.svg +5 -0
  128. package/runtime/arcane/img/upload.svg +5 -0
  129. package/runtime/arcane/modules/AI.js +2048 -0
  130. package/runtime/arcane/modules/AIPreferenceRuntime.js +32 -0
  131. package/runtime/arcane/modules/AIPreferenceTuple.js +92 -0
  132. package/runtime/arcane/modules/AIResponseLength.js +42 -0
  133. package/runtime/arcane/modules/AIResponseURLPolicy.js +626 -0
  134. package/runtime/arcane/modules/AnsiText.js +53 -0
  135. package/runtime/arcane/modules/ApiModelDatabase.js +25 -0
  136. package/runtime/arcane/modules/AppDataScope.js +245 -0
  137. package/runtime/arcane/modules/AppearancePreferences.js +28 -0
  138. package/runtime/arcane/modules/ArcaneCommunicationBridge.js +22 -0
  139. package/runtime/arcane/modules/ArcaneNavigationPolicy.js +135 -0
  140. package/runtime/arcane/modules/ArcaneNetworkPolicy.js +255 -0
  141. package/runtime/arcane/modules/AsyncBoundary.js +161 -0
  142. package/runtime/arcane/modules/BrowserTestSuite.js +326 -0
  143. package/runtime/arcane/modules/CalculatorEngine.js +20 -0
  144. package/runtime/arcane/modules/CaseEvidenceIndexer.js +134 -0
  145. package/runtime/arcane/modules/ChartLibrary.js +35 -0
  146. package/runtime/arcane/modules/ChatRecords.js +13 -0
  147. package/runtime/arcane/modules/CommunicationAppController.js +43 -0
  148. package/runtime/arcane/modules/CommunicationHub.js +16 -0
  149. package/runtime/arcane/modules/CommunicationPreferences.js +13 -0
  150. package/runtime/arcane/modules/CommunicationProviderRegistry.js +16 -0
  151. package/runtime/arcane/modules/ComponentContracts.js +586 -0
  152. package/runtime/arcane/modules/ConfiguredAIChatSession.js +288 -0
  153. package/runtime/arcane/modules/ConversationActionItems.js +488 -0
  154. package/runtime/arcane/modules/ConversationClosingReport.js +274 -0
  155. package/runtime/arcane/modules/ConversationTimebox.js +527 -0
  156. package/runtime/arcane/modules/CoreLocalModelCatalog.js +255 -0
  157. package/runtime/arcane/modules/DBLS.js +171 -0
  158. package/runtime/arcane/modules/DBOPFS.js +1154 -0
  159. package/runtime/arcane/modules/DBOPFSWorker.js +116 -0
  160. package/runtime/arcane/modules/DataMaintenance.js +91 -0
  161. package/runtime/arcane/modules/DevelopmentWorkspace.js +74 -0
  162. package/runtime/arcane/modules/DirectoryPicker.js +109 -0
  163. package/runtime/arcane/modules/DocumentNavigation.js +223 -0
  164. package/runtime/arcane/modules/Errors.js +1025 -0
  165. package/runtime/arcane/modules/GifEncoder.js +29 -0
  166. package/runtime/arcane/modules/HTMLImport.js +114 -0
  167. package/runtime/arcane/modules/InMemoryCommunicationProvider.js +14 -0
  168. package/runtime/arcane/modules/IsolatedModelQuestionRunner.js +275 -0
  169. package/runtime/arcane/modules/LocalAIReadiness.js +870 -0
  170. package/runtime/arcane/modules/LocalAIReadinessController.js +156 -0
  171. package/runtime/arcane/modules/MD.js +111 -0
  172. package/runtime/arcane/modules/Mail.js +352 -0
  173. package/runtime/arcane/modules/MailTransport.mjs +180 -0
  174. package/runtime/arcane/modules/Marked.min.js +71 -0
  175. package/runtime/arcane/modules/MemoryRecords.js +44 -0
  176. package/runtime/arcane/modules/MessageAdvisory.js +38 -0
  177. package/runtime/arcane/modules/ModelDefinition.js +189 -0
  178. package/runtime/arcane/modules/Ollama.js +74 -0
  179. package/runtime/arcane/modules/OllamaModelIdentifier.js +21 -0
  180. package/runtime/arcane/modules/OllamaSettings.js +24 -0
  181. package/runtime/arcane/modules/OpenMeteoWeatherProvider.js +14 -0
  182. package/runtime/arcane/modules/PreferenceStore.js +109 -0
  183. package/runtime/arcane/modules/QRCode.min.js +1 -0
  184. package/runtime/arcane/modules/Questionnaire.js +61 -0
  185. package/runtime/arcane/modules/RecordLinkIndex.js +24 -0
  186. package/runtime/arcane/modules/RecordPassageIndex.js +222 -0
  187. package/runtime/arcane/modules/RecordReviewStore.js +94 -0
  188. package/runtime/arcane/modules/RevocableProjectionLedger.js +1623 -0
  189. package/runtime/arcane/modules/RiskSignalAnalyzer.js +37 -0
  190. package/runtime/arcane/modules/ScamRiskPolicy.js +62 -0
  191. package/runtime/arcane/modules/ScopedOPFSCache.js +183 -0
  192. package/runtime/arcane/modules/ScreenCapture.js +20 -0
  193. package/runtime/arcane/modules/SpeechPlayback.js +581 -0
  194. package/runtime/arcane/modules/StaticDocumentCatalog.js +1248 -0
  195. package/runtime/arcane/modules/SystemAppearance.js +20 -0
  196. package/runtime/arcane/modules/SystemPlatformPresentation.js +51 -0
  197. package/runtime/arcane/modules/SystemToolRegistry.js +28 -0
  198. package/runtime/arcane/modules/TerminalClient.js +52 -0
  199. package/runtime/arcane/modules/TerminalCommandRegistry.js +50 -0
  200. package/runtime/arcane/modules/ThemeBootstrap.js +26 -0
  201. package/runtime/arcane/modules/ThemeManager.js +131 -0
  202. package/runtime/arcane/modules/TimeGuard.js +149 -0
  203. package/runtime/arcane/modules/ToolCallRouter.js +83 -0
  204. package/runtime/arcane/modules/WaitForComponent.js +102 -0
  205. package/runtime/arcane/modules/YouTubeMedia.js +16 -0
  206. package/runtime/arcane/modules/uPlot.LICENSE.txt +21 -0
  207. package/runtime/arcane/modules/uPlot.iife.min.js +2 -0
  208. package/runtime/arcane/modules/uPlot.min.css +1 -0
  209. package/runtime/arcane/security/arcane-network-policy.json +6 -0
  210. package/runtime/strong-type/index.js +352 -0
  211. package/runtime/strong-type/licence +21 -0
  212. package/runtime/strong-type/package.json +45 -0
  213. package/schemas/arcane-app-bundle.schema.json +125 -0
  214. package/schemas/arcane-app.schema.json +329 -0
  215. package/schemas/arcane-lock.schema.json +86 -0
  216. package/schemas/arcane-package.schema.json +224 -0
  217. package/schemas/cli-event.schema.json +122 -0
  218. package/schemas/event-stack.schema.json +152 -0
  219. package/schemas/native-build-plan.schema.json +176 -0
  220. package/schemas/target-adapter.schema.json +117 -0
  221. package/src/app-descriptor.mjs +500 -0
  222. package/src/cli/main.mjs +561 -0
  223. package/src/constants.mjs +31 -0
  224. package/src/dev-server.mjs +718 -0
  225. package/src/doctor.mjs +315 -0
  226. package/src/dom-event-instrumentation.mjs +594 -0
  227. package/src/errors.mjs +75 -0
  228. package/src/event-manager.mjs +1342 -0
  229. package/src/event-queue.mjs +138 -0
  230. package/src/events.mjs +219 -0
  231. package/src/index.mjs +177 -0
  232. package/src/integrated-provider-loader.mjs +432 -0
  233. package/src/native-plan.mjs +698 -0
  234. package/src/native-provider-loader.mjs +1126 -0
  235. package/src/packager/core.mjs +2691 -0
  236. package/src/process.mjs +353 -0
  237. package/src/release-bundle.mjs +2523 -0
  238. package/src/repository.mjs +90 -0
  239. package/src/runtime.mjs +452 -0
  240. package/src/scaffold.mjs +380 -0
  241. package/src/targets/index.mjs +436 -0
  242. package/src/templates/assets/app-icon.png +0 -0
  243. package/src/templates/workspace-template.mjs +388 -0
  244. package/src/testing-loader.mjs +9 -0
  245. package/src/testing.mjs +427 -0
  246. package/src/toolchain.mjs +1335 -0
  247. package/src/update-check.mjs +307 -0
  248. package/src/workspace.mjs +449 -0
@@ -0,0 +1,873 @@
1
+ # Arcane AI Data Contracts
2
+
3
+ This reference defines the request and result objects used by Arcane's
4
+ provider-neutral AI, local AI, speech, isolated-inference, and direct Ollama
5
+ APIs. Start with the method index in the [Arcane API Reference](arcane-api.md).
6
+
7
+ The type names below are documentation notation for plain JavaScript values.
8
+ They are not TypeScript declarations.
9
+
10
+ ## Contract conventions
11
+
12
+ | Input style | Unknown keys | Object rules |
13
+ |---|---|---|
14
+ | Exact record | Rejected | A plain object with exactly the documented own data properties. Every field is required unless marked optional. Arrays, accessors, symbol keys, and non-plain objects are rejected. |
15
+ | Closed object | Rejected at the documented level | A plain object containing only the documented top-level keys. Provider-native nested values may have additional provider-defined structure. |
16
+ | Settings object | Currently ignored | A plain object whose documented keys are read. Callers should still send only documented keys. |
17
+
18
+ `Required` means the caller must supply the field. `Conditional` means the field
19
+ is required only under the condition in its constraints. A safe integer passes
20
+ `Number.isSafeInteger`. Byte limits use UTF-8 unless a row says characters,
21
+ encoded text, or decoded bytes.
22
+
23
+ Authorization and host admission occur before method-specific validation. An
24
+ unauthorized caller can therefore receive a capability or host error before an
25
+ input error. Rejections use `Arcane.Error`; never parse its human-readable
26
+ message as a protocol value.
27
+
28
+ These rows define the portable caller contract. Some provider-settings and
29
+ speech validators currently coerce or ignore particular off-contract values
30
+ differently on desktop Core and Android. Callers must send the documented types
31
+ and keys and must not depend on permissive host behavior or uniform rejection of
32
+ invalid input. The provider-neutral AI, local-AI, speech, and direct Ollama
33
+ methods in this document currently use method-local validators rather than
34
+ canonical entries in `method-contracts.json`; catalog metadata must not invent
35
+ semantic attributes that the registry does not define.
36
+
37
+ ## Provider-neutral AI
38
+
39
+ ### AI chat request
40
+
41
+ `Arcane.ai.chat(request)` accepts a closed `AIChatRequest`.
42
+
43
+ | Field | Type | Required | Constraints / default | Description |
44
+ |---|---|---:|---|---|
45
+ | `messages` | [`AIChatMessage[]`](#ai-chat-message) | Yes | 1-128 records; combined content at most 512 KiB | Conversation sent to the configured provider. |
46
+ | `expectedProvider` | `"ollama" \| "openai"` | No | Omitted means no caller-side provider binding | Rejects with `AI_PROVIDER_CHANGED` when the configured provider changed before dispatch. |
47
+ | `format` | `"json" \| "" \| null` | No | Omit, `null`, or `""` for text | Portable output-format control. |
48
+ | `model` | `string` | No | Local model pattern `[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}` | Local Ollama override. The OpenAI path always uses the configured, account-validated model. |
49
+ | `options` | JSON object | No | Ollama only | Provider-native generation options. |
50
+ | `tools` | JSON array | No | Ollama only | Provider-native tool definitions. |
51
+ | `keep_alive` | JSON value | No | Ollama only | Provider-native model-residency control. |
52
+ | `think` | JSON value | No | Ollama only | Provider-native reasoning control. |
53
+ | `logprobs` | JSON value | No | Ollama only | Provider-native log-probability control. |
54
+ | `top_logprobs` | JSON value | No | Ollama only | Provider-native log-probability count. |
55
+
56
+ For a provider-portable request, send only `messages`, optional
57
+ `expectedProvider`, and optional `format`.
58
+
59
+ ```js
60
+ const profile = await Arcane.ai.profile();
61
+
62
+ const result = await Arcane.ai.chat({
63
+ expectedProvider: profile.provider,
64
+ messages: [
65
+ { role: "system", content: "Answer briefly and accurately." },
66
+ { role: "user", content: "What models are available?" }
67
+ ]
68
+ });
69
+ ```
70
+
71
+ ### AI chat message
72
+
73
+ Every `AIChatMessage` is an exact record.
74
+
75
+ | Field | Type | Required | Constraints / default | Description |
76
+ |---|---|---:|---|---|
77
+ | `role` | `"system" \| "user" \| "assistant"` | Yes | Exact lowercase value | Message author role. |
78
+ | `content` | `string` | Yes | Nonempty; at most 131,072 characters | Message text. |
79
+
80
+ No other message fields are accepted.
81
+
82
+ ### AI chat result
83
+
84
+ `AIChatResult` is normalized across configured Ollama and OpenAI chat.
85
+
86
+ | Field | Type | Required | Constraints / default | Description |
87
+ |---|---|---:|---|---|
88
+ | `provider` | `"arcane-ollama" \| "openai"` | Yes | - | Provider that completed the request. |
89
+ | `model` | `string` | Yes | Bounded provider model identifier | Model used for the response. |
90
+ | `message.role` | `"assistant"` | Yes | - | Normalized response role. |
91
+ | `message.content` | `string` | Yes | At most 4 MiB retained | Assistant response text. |
92
+ | `message.thinking` | `string` | No | Ollama only; at most 4 MiB retained | Provider reasoning text when present. |
93
+ | `message.toolCalls` | `array` | No | Ollama provider-native records | Tool calls when present. |
94
+ | `done` | `boolean` | Yes | OpenAI returns `true` | Completion flag. |
95
+ | `doneReason` | `string \| null` | Yes | At most 128 characters | Completion reason. |
96
+ | `promptEvalCount` | `integer \| null` | Yes | Nonnegative when present | Prompt token/evaluation count. |
97
+ | `evalCount` | `integer \| null` | Yes | Nonnegative when present | Completion token/evaluation count. |
98
+
99
+ ### AI profile
100
+
101
+ `Arcane.ai.profile()` returns `AIProfile`.
102
+
103
+ | Field | Type | Required | Constraints / default | Description |
104
+ |---|---|---:|---|---|
105
+ | `provider` | `"ollama" \| "openai"` | Yes | - | Selected provider. |
106
+ | `model` | `string` | Yes | Effective configured model | Model used by provider-neutral chat. |
107
+ | `configured` | `boolean` | Yes | - | Required provider configuration is present. |
108
+ | `local` | `boolean` | Yes | `true` only for Ollama | Whether inference remains local. |
109
+ | `responseLength` | `"low" \| "medium" \| "high"` | Yes | Legacy invalid/missing state resolves to `"medium"` | Conversational response target, not a provider token limit. |
110
+
111
+ An OpenAI profile is returned only after Arcane proves a protected credential
112
+ exists and the configured model is available to that account.
113
+
114
+ ### AI provider settings input
115
+
116
+ `Arcane.ai.saveProviderSettings(settings)` reads the documented fields from an
117
+ `AIProviderSettingsInput` patch. Omitted keys preserve the current value. Send
118
+ only these keys and the documented value types; do not rely on a host ignoring
119
+ unknown fields or coercing `removeToken`.
120
+
121
+ | Field | Type | Required | Constraints / default | Description |
122
+ |---|---|---:|---|---|
123
+ | `provider` | `"ollama" \| "openai"` | No | Current provider | Provider to select. |
124
+ | `openAIModel` | `string` | Conditional | Pattern `[A-Za-z0-9][A-Za-z0-9._:-]{0,127}`; required for OpenAI | Account-accessible OpenAI model. |
125
+ | `responseLength` | `"low" \| "medium" \| "high"` | No | Current value | Conversational response target. |
126
+ | `token` | `string` | No | Trimmed, starts with `sk-`, 20-512 characters | Replacement OpenAI credential. It is protected and never returned. |
127
+ | `removeToken` | `boolean` | No | Only `true` requests deletion | Removes the stored credential. A supplied `token` becomes the final credential. |
128
+
129
+ Arcane verifies the selected OpenAI model when OpenAI is selected and validates
130
+ a supplied replacement credential before persistence. Ollama-selected settings
131
+ may retain a dormant OpenAI model; Arcane revalidates it before a later switch
132
+ to OpenAI. Credential and settings mutations are rolled back together when
133
+ possible if the save fails.
134
+
135
+ ### AI provider settings result
136
+
137
+ `Arcane.ai.providerSettings()` and a successful save return
138
+ `AIProviderSettingsResult`.
139
+
140
+ | Field | Type | Required | Constraints / default | Description |
141
+ |---|---|---:|---|---|
142
+ | `provider` | `"ollama" \| "openai"` | Yes | - | Selected provider. |
143
+ | `openAIModel` | `string` | Yes | May be empty when OpenAI is not selected | Saved OpenAI model. |
144
+ | `openAIConfigured` | `boolean` | Yes | - | A protected credential exists. |
145
+ | `responseLength` | `"low" \| "medium" \| "high"` | Yes | - | Saved response target. |
146
+
147
+ Credentials are never included.
148
+
149
+ ### Local AI inventory
150
+
151
+ `Arcane.ai.models()` returns `LocalAIInventory`, not a bare array. This is raw
152
+ diagnostic inventory, not the admitted application selector catalog.
153
+
154
+ | Field | Type | Required | Constraints / default | Description |
155
+ |---|---|---:|---|---|
156
+ | `provider` | `"arcane-ollama"` | Yes | - | Catalog source. |
157
+ | `models` | `OllamaInventoryModel[]` | Yes | At most 512 records | Normalized installed inventory. |
158
+
159
+ Each `OllamaInventoryModel` contains:
160
+
161
+ | Field | Type | Required | Constraints / default | Description |
162
+ |---|---|---:|---|---|
163
+ | `name` | `string` | Yes | Local model-name pattern | Installed model identifier. |
164
+ | `modifiedAt` | `string \| null` | Yes | At most 64 characters | Provider timestamp when available. |
165
+ | `sizeBytes` | `integer \| null` | Yes | Nonnegative safe integer | Installed size when valid. |
166
+ | `digest` | `string \| null` | Yes | Lowercase 64-character hexadecimal digest | Model digest when valid. |
167
+ | `family` | `string \| null` | Yes | At most 128 characters | Provider-reported family. |
168
+ | `parameterSize` | `string \| null` | Yes | At most 64 characters | Provider parameter-size label. |
169
+ | `quantization` | `string \| null` | Yes | At most 64 characters | Provider quantization label. |
170
+
171
+ ### AI provider model catalog
172
+
173
+ `Arcane.ai.providerModels()` returns `AIProviderModelCatalog` after querying the
174
+ protected OpenAI credential's account.
175
+
176
+ | Field | Type | Required | Constraints / default | Description |
177
+ |---|---|---:|---|---|
178
+ | `provider` | `"openai"` | Yes | - | Catalog source. |
179
+ | `models` | `string[]` | Yes | Each value matches the OpenAI model pattern | Sorted account-accessible identifiers. |
180
+
181
+ This method can perform a network request. It does not return Ollama models.
182
+
183
+ ## Local AI discovery and lifecycle
184
+
185
+ ### Local AI status v2
186
+
187
+ `Arcane.localAI.status()` takes no arguments and returns `LocalAIStatusV2`.
188
+ Concurrent callers in one Core process can share the same active discovery.
189
+ An admitted development Android provider uses the same schema version with the
190
+ exact `user-managed-loopback` discriminator described below.
191
+
192
+ | Field | Type | Required | Constraints / default | Description |
193
+ |---|---|---:|---|---|
194
+ | `schemaVersion` | `2` | Yes | Literal | Status schema. |
195
+ | `providerMode` | `"user-managed-loopback"` | Android only | Omitted by desktop Core | Identifies the narrow Android provider without changing `Arcane.runtime.current().managedLocalAI`, which remains false. |
196
+ | `runtime` | object | Yes | Desktop Core or bounded Android provider identity | Runtime authority and whether desktop native resource admission is active. |
197
+ | `policy` | object | Yes | See below | Package-bound model policy. |
198
+ | `ollama` | object | Yes | See below | Ollama discovery state. |
199
+ | `admission` | object | Yes | See below | Native-admission summary. |
200
+ | `speech` | object | Yes | See below | Independent speech readiness. |
201
+ | `models` | object | Yes | `{ollama, speech, transcription}` arrays | Admitted catalogs. |
202
+
203
+ `policy` fields:
204
+
205
+ | Field | Type | Required | Constraints / default | Description |
206
+ |---|---|---:|---|---|
207
+ | `verified_only` | `boolean` | Yes | Package policy | Whether only declared verified models are considered. |
208
+ | `source` | `"package-bound-application-policy"` | Yes | Literal | Policy source. |
209
+ | `unverifiedInferenceAuthorized` | `boolean` | Yes | Requires explicit package authority | Whether installed unverified models may be considered for inference. |
210
+
211
+ `ollama` fields:
212
+
213
+ | Field | Type | Required | Constraints / default | Description |
214
+ |---|---|---:|---|---|
215
+ | `available` | `boolean` | Yes | - | Core obtained a valid bounded catalog. |
216
+ | `modelCapabilitiesVerified` | `boolean` | Yes | - | Capability discovery completed. |
217
+ | `nativeAdmissionEnforced` | `boolean` | Yes | `true` for desktop Core; `false` for Android user-managed loopback | Whether desktop native resource admission is enforced. Android still applies its generated package-policy and provider-inspection boundary. |
218
+ | `activeParallelRequests` | `integer` | Desktop Core | Positive safe integer | Current machine-wide managed Ollama parallel request count used for active-fit evidence. |
219
+ | `errorCode` | `string \| null` | Yes | Normalized code | Discovery failure code. |
220
+
221
+ `admission` fields:
222
+
223
+ | Field | Type | Required | Constraints / default | Description |
224
+ |---|---|---:|---|---|
225
+ | `policyVersion` | `integer` | Yes | Currently `1` | Resource-policy version. |
226
+ | `enforcedBy` | `string` | Yes | Bounded host-owned identifier | Admission authority; renderers must not interpret it as reusable authorization. |
227
+ | `evaluatedModels` | `integer` | Yes | Nonnegative | Candidate count evaluated. |
228
+ | `admittedModels` | `integer` | Yes | 0 through `evaluatedModels` | Candidate count admitted at one parallel request. A model can still have `runnable:false` when the active machine-wide parallel count exceeds its current model-specific ceiling. |
229
+ | `rejected` | `array` | Yes | `{id, compatibility}` records | Rejected candidates and admission evidence. |
230
+
231
+ `speech` fields:
232
+
233
+ | Field | Type | Required | Constraints / default | Description |
234
+ |---|---|---:|---|---|
235
+ | `available` | `boolean` | Yes | - | Synthesis or transcription is available. |
236
+ | `reachable` | `boolean` | Yes | - | Core validated the health endpoint. |
237
+ | `synthesisAvailable` | `boolean` | Yes | - | Kokoro readiness. |
238
+ | `transcriptionAvailable` | `boolean` | Yes | - | Whisper readiness. |
239
+ | `synthesisErrorCode` | `string \| null` | Yes | - | Synthesis failure/readiness code. |
240
+ | `transcriptionErrorCode` | `string \| null` | Yes | - | Transcription failure/readiness code. |
241
+ | `errorCode` | `string \| null` | Yes | - | Overall speech failure code. |
242
+
243
+ `models.ollama` contains [`LocalAIModel`](#local-ai-model) records.
244
+ `models.speech` and `models.transcription` contain
245
+ [`LocalAIServiceModel`](#local-ai-service-model) records. An unavailable service
246
+ resolves as service-local status data where possible; it never silently changes
247
+ providers.
248
+
249
+ For `providerMode:"user-managed-loopback"`, the Android host calls only the
250
+ fixed `127.0.0.1:11434` Ollama service and fixed host-owned loopback speech
251
+ service. It returns only installed package-policy models that passed its bounded
252
+ provider inspection, repeats model admission before `ollama.chat`, and merges
253
+ the independently bounded Kokoro and Whisper role health and catalogs. The host
254
+ does not expose recovery or model mutation. The renderer never calls either
255
+ loopback API directly.
256
+
257
+ Android Linux Terminal, Ollama, and every model lifecycle action remain user-owned. Plain
258
+ loopback Ollama has no caller authentication; other local applications or
259
+ processes may call it, race the host's checks, contend for resources, or deny
260
+ service. This is unsigned development behavior, not release support, managed
261
+ service ownership, or an isolated-inference guarantee. Android exposes no
262
+ application-owned isolated-question or repository extension unless generated
263
+ package and method policy explicitly admit it.
264
+
265
+ ### Local AI model
266
+
267
+ | Field | Type | Required | Constraints / default | Description |
268
+ |---|---|---:|---|---|
269
+ | `id`, `name` | `string` | Yes | Equal model identifiers | Snapshot selection identifier and Ollama name. |
270
+ | `provider` | `"ollama"` | Yes | Literal | Provider. |
271
+ | `roles` | `array` | Yes | Currently empty | Reserved role catalog. |
272
+ | `managed` | `boolean` | Yes | - | Declared by package policy. |
273
+ | `installed` | `boolean` | Yes | - | Runnable alias or authorized model is installed. |
274
+ | `admitted` | `true` | Yes | Literal | Current serial-fit admission. This is not proof that the active parallel setting fits. |
275
+ | `runnable`, `creatable`, `pullable`, `verified` | `boolean` | Yes | - | Managed lifecycle state. `runnable:false` can mean the active parallel setting exceeds the model's current ceiling. |
276
+ | `capabilitiesVerified`, `available` | `true` | Yes | Literal | Capability and availability proof. |
277
+ | `modifiedAt` | `string \| null` | Yes | - | Installed timestamp. |
278
+ | `sizeBytes` | `integer \| null` | Yes | Nonnegative safe integer | Model size. |
279
+ | `digest` | `string \| null` | Yes | 64-character hexadecimal value | Installed digest. |
280
+ | `family`, `parameterSize`, `quantization` | `string \| null` | Yes | Bounded diagnostic strings | Provider metadata. |
281
+ | `compatibility` | [`ModelResourceAdmission`](#model-resource-admission) | Yes | `admitted:true` | Native resource and definition evidence. |
282
+
283
+ This record is snapshot evidence, not reusable authorization. Core re-admits the
284
+ exact model and requested context before inference.
285
+
286
+ ### Local AI service model
287
+
288
+ | Field | Type | Required | Constraints / default | Description |
289
+ |---|---|---:|---|---|
290
+ | `id` | `"kokoro" \| "whisper-small"` | Yes | - | Model identifier. |
291
+ | `name` | `"Kokoro" \| "Whisper Small"` | Yes | - | Display name. |
292
+ | `provider` | `"speech"` | Yes | Literal | Service provider. |
293
+ | `roles` | `["tts"] \| ["stt"]` | Yes | One role | Supported operation. |
294
+ | `available` | `true` | Yes | Literal | Availability in this snapshot. |
295
+ | `engine` | `string` | Yes | Health-validated identifier | Native engine. |
296
+
297
+ ### Model resource admission
298
+
299
+ `ModelResourceAdmission` is a union. Early failures can omit diagnostic fields;
300
+ callers must not assume every field exists.
301
+
302
+ | Field | Type | Required | Constraints / default | Description |
303
+ |---|---|---:|---|---|
304
+ | `policyVersion` | `integer` | Yes | Currently `1` | Resource-policy version. |
305
+ | `admitted` | `boolean` | Yes | - | Current fit decision. |
306
+ | `status` | `"compatible" \| "incompatible" \| "evidence-unavailable"` | Yes | - | Admission classification. |
307
+ | `code` | `string \| null` | Yes | `null` on success | Stable result code. |
308
+ | `message` | `string` | Yes | At most 512 characters | Human-readable result. |
309
+ | `resolution` | `string \| null` | Yes | At most 512 characters | Suggested remediation. |
310
+ | `operation` | `"inference" \| "create" \| "pull"` | No | Evidence-dependent | Evaluated operation. |
311
+ | `model` | `string` | No | At most 256 characters | Evaluated model. |
312
+ | `modelBytes`, `downloadBytes`, `contextTokens`, `nativeContextTokens`, `kvCacheBytes` | `integer \| null` | No | Positive when present | Model, transfer, requested/native context, and K/V-cache evidence. |
313
+ | `parallelism` | `integer` | No | Positive safe integer | Parallel request count evaluated by this admission record. |
314
+ | `activeParallelRequests` | `integer` | No | Positive safe integer | Current machine-wide managed Ollama setting observed for the snapshot. |
315
+ | `maxAllowedParallelRequests` | `integer \| null` | No | `null`, 0, or a positive safe integer | Largest count admitted by the same immutable model/resource snapshot. It is solved directly from the model's K/V-cache equation and available working-set bytes, without a product ceiling. `null` means evidence was unavailable; `0` means even one request was proven memory-incompatible. |
316
+ | `activeParallelRequestsAllowed` | `boolean \| null` | No | - | Whether the active count is within `maxAllowedParallelRequests`; `null` preserves unknown evidence. |
317
+ | `runtimeHeadroomBytes`, `requiredWorkingSetBytes` | `integer` | No | Positive | Derived working-set requirements. |
318
+ | `requiredAdditionalBytes`, `availableWorkingSetBytes` | `integer` | No | Nonnegative | Additional requirement and available capacity. |
319
+ | `loadedModelBytes`, `targetResidentBytes` | `integer` | No | Nonnegative | Current residency evidence. |
320
+ | `checks` | [`ModelResourceCheck[]`](#model-resource-checks) | No | - | Individual capacity checks. |
321
+ | `definitionVerified`, `baseModelInstalled`, `creationRequired`, `pullRequired` | `boolean` | No | Managed workflows | Managed lifecycle evidence. |
322
+ | `registryEvidence` | object | No | Opaque diagnostic shape | Preflight detail; never an authorization token. |
323
+
324
+ Other bounded diagnostics may appear on failures. Branch on `admitted`,
325
+ `status`, and `code`; treat additional evidence as display-only.
326
+
327
+ ### Model resource checks
328
+
329
+ A working-set `ModelResourceCheck` contains:
330
+
331
+ | Field | Type | Required | Constraints / default | Description |
332
+ |---|---|---:|---|---|
333
+ | `id` | `"working-set"` | Yes | Literal | Check identifier. |
334
+ | `ok` | `boolean` | Yes | - | Pass/fail result. |
335
+ | `requiredBytes`, `totalRequiredBytes`, `availableBytes` | `integer` | Yes | Nonnegative | Required additional, required total, and available bytes. |
336
+ | `systemFreeBytes`, `systemReserveBytes`, `usableSystemBytes` | `integer` | Yes | Nonnegative | System-memory evidence. |
337
+ | `usableGpuBytes`, `loadedModelBytes`, `targetResidentBytes` | `integer` | Yes | Nonnegative | Accelerator and residency evidence. |
338
+
339
+ A pull may add a `"model-store"` check with `ok`, `requiredBytes`,
340
+ `availableBytes`, `storageFreeBytes`, and `storageReserveBytes`.
341
+
342
+ Admission proves only current fit. It does not prove safety, output quality,
343
+ license, provenance, supplier identity, future capacity, or stability under
344
+ later concurrent workloads.
345
+
346
+ ### Local AI platform result
347
+
348
+ `Arcane.localAI.ensurePlatform()` takes no arguments. It is a Provisioner-only,
349
+ exclusive post-install reconciliation. It retries when settings change during
350
+ the operation and rejects with `ARCANE_AI_PROFILE_CHANGED` after three stale
351
+ plans instead of overwriting newer settings.
352
+
353
+ `LocalAIPlatformResult` always contains an [`ArcaneOperation`](#arcane-operation)
354
+ and one of these branches.
355
+
356
+ OpenAI-selected branch:
357
+
358
+ | Field | Type | Required | Constraints / default | Description |
359
+ |---|---|---:|---|---|
360
+ | `local` | object | Yes | `{available:false, reason:"openai-selected"}` | Local reconciliation was intentionally skipped. |
361
+ | `fallback.provider` | `"openai"` | Yes | Literal | Explicit selected provider. |
362
+ | `fallback.model` | `string` | Yes | Protected-credential account-validated model | Selected OpenAI model. |
363
+ | `fallback.configured` | `true` | Yes | Literal | Required credential and model are valid. |
364
+ | `loaded` | object | Yes | `{loaded:false, provider:"openai", model}` | No local model was loaded. |
365
+ | `operation` | [`ArcaneOperation`](#arcane-operation) | Yes | Completed | Exclusive operation receipt. |
366
+
367
+ Local branch:
368
+
369
+ | Field | Type | Required | Constraints / default | Description |
370
+ |---|---|---:|---|---|
371
+ | `local.available` | `true` | Yes | Literal | Local AI is available. |
372
+ | `local.model` | `string` | Yes | Managed selected model | Ready model definition. |
373
+ | `local.alias` | `string` | Yes | Managed alias | Selected runtime alias. |
374
+ | `local.variant` | `string` | Yes | Arcane model variant | Selected size. |
375
+ | `local.compatibility` | [`ModelResourceAdmission`](#model-resource-admission) | Yes | `admitted:true` | Final native admission. |
376
+ | `local.recommendationDegraded` | `boolean` | Yes | - | Automatic selection used a smaller candidate after capacity rejection. |
377
+ | `local.candidateFailures` | `array` | Yes | Empty unless an earlier automatic candidate failed | Bounded prior failures. |
378
+ | `fallback` | `null` | Yes | - | Arcane did not silently change providers. |
379
+ | `loaded` | object | Yes | See below | Managed boot-load result. |
380
+ | `operation` | [`ArcaneOperation`](#arcane-operation) | Yes | Completed | Exclusive operation receipt. |
381
+
382
+ Each candidate failure is `{variant, kind, code, message, resolution}`. `kind`
383
+ is `"capacity"`, `"evidence-unavailable"`, or `"fatal"`; only a capacity
384
+ failure allows Automatic mode to try the next smaller candidate.
385
+
386
+ `loaded` is a union. Both branches contain `loaded`, `provider`, and `model`.
387
+ The successful local branch also contains `keepAlive` and `contextLength`, where
388
+ `contextLength:null` means Automatic.
389
+
390
+ ### Local AI recovery request
391
+
392
+ `Arcane.localAI.recover(request)` accepts an exact `LocalAIRecoveryRequest`.
393
+
394
+ | Field | Type | Required | Constraints / default | Description |
395
+ |---|---|---:|---|---|
396
+ | `services` | `string[]` | Yes | Nonempty, duplicate-free subset of `"ollama"` and `"speech"` | Existing Arcane-managed services to start and verify. |
397
+
398
+ ### Local AI recovery result
399
+
400
+ | Field | Type | Required | Constraints / default | Description |
401
+ |---|---|---:|---|---|
402
+ | `ready` | `true` | Yes | Literal | All requested services are ready. |
403
+ | `services` | `array` | Yes | Canonical Ollama-then-speech order | Per-service results. |
404
+ | `operation` | [`ArcaneOperation`](#arcane-operation) | Yes | Completed | Privileged exclusive operation. |
405
+
406
+ Every service result is exact:
407
+
408
+ | Field | Type | Required | Constraints / default | Description |
409
+ |---|---|---:|---|---|
410
+ | `id` | `"ollama" \| "speech"` | Yes | - | Service identifier. |
411
+ | `serviceName` | `"ArcaneOllama" \| "ArcaneLocalSpeech"` | Yes | - | Operating-system service name. |
412
+ | `endpoint` | `string` | Yes | Fixed `127.0.0.1` health/version endpoint | Verified loopback endpoint. |
413
+ | `state` | `"running"` | Yes | Literal | Verified state. |
414
+ | `ready` | `true` | Yes | Literal | Readiness proof. |
415
+ | `started` | `boolean` | Yes | - | This request issued the start. |
416
+
417
+ Recovery starts an existing approved registration. It does not install,
418
+ replace, stop, or silently reconfigure a service.
419
+
420
+ ### Local AI parallel request configuration
421
+
422
+ `Arcane.localAI.setParallelRequests(request)` accepts an exact
423
+ `LocalAIParallelRequestsRequest`:
424
+
425
+ | Field | Type | Required | Constraints / default | Description |
426
+ |---|---|---:|---|---|
427
+ | `model` | `string` | Yes | Exact app-owned verified model identifier | Model whose declared definition and native metadata govern the calculation and subsequent load. |
428
+ | `parallelRequests` | `integer` | Yes | Nonnegative safe integer | `0` requests the maximum currently allowed; a positive value is a requested ceiling and is clamped down when necessary. |
429
+ | `contextTokens` | `integer` | No | Positive safe integer; defaults to verified Modelfile `num_ctx` | Exact per-request context evaluated and used to load the model. The model's native metadata, rather than an Arcane product range, supplies the maximum. |
430
+
431
+ A successful `LocalAIParallelRequestsResult` contains:
432
+
433
+ | Field | Type | Required | Constraints / default | Description |
434
+ |---|---|---:|---|---|
435
+ | `schemaVersion` | `1` | Yes | Literal | Result schema. |
436
+ | `model` | `string` | Yes | Exact verified alias | Model ensured and loaded. |
437
+ | `contextTokens`, `nativeContextTokens` | `integer \| null` | Yes | Positive safe integers when present | Requested context and model-native limit when metadata provides one. |
438
+ | `requestedParallelRequests` | `integer` | Yes | Nonnegative safe integer | Caller input. |
439
+ | `requestMode` | `"maximum-allowed" \| "requested-ceiling"` | Yes | Derived from input | Interpretation of the request. |
440
+ | `previousParallelRequests` | `integer` | Yes | Positive safe integer | Proven setting before the operation. |
441
+ | `maxAllowedParallelRequests` | `integer` | Yes | Positive safe integer | Largest count admitted by the resource state used for the effective decision. A changed path uses a fresh stopped-service snapshot. |
442
+ | `allowedParallelRequests`, `effectiveParallelRequests` | `integer` | Yes | Positive safe integers; equal | Clamped target and proven effective count used for the load. |
443
+ | `requestedAllowed`, `clamped` | `boolean` | Yes | - | Whether a positive request fit without reduction and whether reduction occurred. Auto (`0`) is allowed and is not called clamped. |
444
+ | `changed`, `restarted` | `boolean` | Yes | - | Whether the final service setting changed and whether the managed service actually restarted. A resource change observed after stopping can make `restarted:true` and `changed:false`; the receipt reports both facts independently. |
445
+ | `healthy`, `loaded` | `true` | Yes | Literal | Post-operation service and model readiness. |
446
+ | `loadedModel` | object | Yes | `{name,contextLength}` | Bounded `/api/ps` confirmation; provider-reported `contextLength` may represent runner allocation. |
447
+ | `serviceScope` | `"machine"` | Yes | Literal | The Ollama setting is global even though Arcane selected it from one model's evidence. |
448
+ | `unloadedModels` | `string[]` | Yes | Bounded pre-restart identifiers | Resident models evicted by the restart; empty on a no-op. |
449
+ | `definitionVerified` | `true` | Yes | Literal | Exact alias was verified after any required create/repair. |
450
+ | `modelSource` | `"verified-alias" \| "installed-base" \| "registry-preflight"` | Yes | - | Evidence source used for the pre-change capacity calculation. |
451
+ | `admission` | [`ModelResourceAdmission`](#model-resource-admission) | Yes | `admitted:true` | Fresh active-setting admission after ensure/repair and before load. |
452
+ | `operation` | [`ArcaneOperation`](#arcane-operation) | Yes | Completed | Privileged exclusive operation receipt. |
453
+
454
+ Core snapshots one exact model/resource state and solves the maximum directly
455
+ from the model metadata's K/V-cache byte ratio and the snapshot's available
456
+ working-set bytes. There is no candidate-count search and no Arcane product
457
+ ceiling. The largest exact integer representable by the JavaScript/JSON API is a
458
+ transport constraint, not a model-capacity claim. The result is a current
459
+ memory/resource admission with explicit reserves, not a performance optimum or
460
+ a promise of future availability. If the tentative target already equals the
461
+ current setting, Core does not stop Ollama. Otherwise the guarded transaction
462
+ stops and proves the service, takes one fresh stopped-service resource snapshot,
463
+ re-solves the effective count, changes only `OLLAMA_NUM_PARALLEL` when that final
464
+ count differs, and starts/proves the service. This unloads every resident Ollama
465
+ model and can terminate in-flight local inference.
466
+ It then ensures or repairs the exact alias, loads it with the requested context
467
+ and indefinite residency, and returns only after `/api/ps` confirms the model.
468
+ If loading fails after a setting change, Core attempts to restore the prior count.
469
+ The operation does not drain unrelated Core processes or direct loopback clients.
470
+ Automatic mutation is currently implemented only by the managed Microsoft NT
471
+ adapter. Linux validates the request but returns a `501` manual-systemd error;
472
+ Android's user-managed loopback mode does not invoke this desktop Core method.
473
+
474
+ ### Arcane operation
475
+
476
+ Successful mutating AI methods include `ArcaneOperation`.
477
+
478
+ | Field | Type | Required | Constraints / default | Description |
479
+ |---|---|---:|---|---|
480
+ | `id` | `string` | Yes | UUID | Operation identifier. |
481
+ | `type` | `string` | Yes | Method-specific | Operation type. |
482
+ | `status` | `string` | Yes | Successful returned operations are `"completed"` | State. |
483
+ | `startedAt` | ISO timestamp `string` | Yes | - | Start time. |
484
+ | `completedAt` | ISO timestamp `string \| null` | Yes | Present on completion | Completion time. |
485
+ | `progress` | `number` | Yes | 0-100; success is 100 | Latest progress. |
486
+ | `currentStep` | `string \| null` | Yes | - | Latest visible step. |
487
+ | `progressDetails` | `object \| null` | Yes | Operation-specific | Structured progress. |
488
+ | `credentials` | `array` | Yes | Normally empty for AI lifecycle work | Host-issued credential artifacts, if any; do not log or persist them. |
489
+ | `error` | `object \| null` | Yes | `null` on success | Normalized operation error. |
490
+
491
+ ## Speech
492
+
493
+ ### Speech status
494
+
495
+ `Arcane.speech.status()` takes no arguments and returns `SpeechStatus`.
496
+
497
+ | Field | Type | Required | Constraints / default | Description |
498
+ |---|---|---:|---|---|
499
+ | `ready` | `boolean` | Yes | `true` only when TTS and STT are ready | Aggregate readiness. |
500
+ | `synthesisAvailable` | `boolean` | Yes | Core/native-host field | Independent Kokoro readiness. |
501
+ | `transcriptionAvailable` | `boolean` | Yes | Core/native-host field | Independent Whisper readiness. |
502
+ | `status` | `string` | Yes | Bounded health identifier | Native service state. |
503
+ | `ttsEngine` | `string` | Yes | Health-validated | Text-to-speech engine. |
504
+ | `sttEngine` | `string` | Yes | Health-validated | Speech-to-text engine. |
505
+
506
+ Unlike `localAI.status()`, this direct call rejects when Core cannot reach and
507
+ validate the speech health response.
508
+
509
+ ### Speech synthesis request
510
+
511
+ `Arcane.speech.synthesize(request)` accepts the portable
512
+ `SpeechSynthesisRequest` fields below. Supply the documented primitive types and
513
+ lowercase values; do not rely on host-specific coercion or empty-string
514
+ defaulting.
515
+
516
+ | Field | Type | Required | Constraints / default | Description |
517
+ |---|---|---:|---|---|
518
+ | `input` | `string` | Yes | Trimmed, nonempty, at most 4,000 characters | Text to synthesize. |
519
+ | `model` | `"kokoro"` | No | Default `"kokoro"`; only supported value | Synthesis model. |
520
+ | `voice` | `string` | No | Default `"af_heart"`; `[a-z0-9][a-z0-9_-]{0,63}` | Kokoro voice. |
521
+ | `responseFormat` | `"opus" \| "wav"` | No | Default `"opus"` | Audio format. |
522
+ | `speed` | `number` | No | Default `1`; 0.5-2 inclusive | Speaking speed. |
523
+
524
+ ### Speech synthesis result
525
+
526
+ | Field | Type | Required | Constraints / default | Description |
527
+ |---|---|---:|---|---|
528
+ | `audioBase64` | `string` | Yes | Base64 for 1 byte through 6 MiB of audio | Encoded audio. |
529
+ | `contentType` | `"audio/ogg" \| "audio/wav"` | Yes | Matches the result encoding | Media type. |
530
+
531
+ ### Speech transcription request
532
+
533
+ `Arcane.speech.transcribe(request)` accepts an exact
534
+ `SpeechTranscriptionRequest`.
535
+
536
+ | Field | Type | Required | Constraints / default | Description |
537
+ |---|---|---:|---|---|
538
+ | `audioBase64` | `string` | Yes | Canonical base64; encoded at most 8 MiB; decoded 1 byte through 6 MiB | Media bytes labeled as WebM. The bridge validates encoding and bounds, while the fixed speech service parses the container. |
539
+ | `mimeType` | `string` | No | Default `"audio/webm"`; base type must be `audio/webm` | Media type; codec parameters may follow. |
540
+ | `model` | `string` | No | Default `"whisper-small"`; `whisper(?:[._-][a-z0-9]+)*` | Whisper identifier. The fixed service rejects unsupported variants. |
541
+
542
+ ### Speech transcription result
543
+
544
+ | Field | Type | Required | Constraints / default | Description |
545
+ |---|---|---:|---|---|
546
+ | `text` | `string` | Yes | Trimmed; response limited to 64 KiB | Transcript. |
547
+
548
+ Application-owned inference extensions define their request, callback, proof,
549
+ and isolation schemas with the owning package. They are included in the same
550
+ developer-reference completeness check but do not become generic Arcane AI
551
+ contracts merely because Core transports them.
552
+
553
+ ## Direct Ollama API
554
+
555
+ Direct Ollama calls are local Core APIs, not provider-neutral contracts. Their
556
+ request objects are closed top-level plain objects. Core rejects unknown
557
+ top-level fields, non-JSON-compatible values, and encoded requests larger than
558
+ 8 MiB. Nested provider-native objects are forwarded for Ollama to validate.
559
+
560
+ ### Ollama model name
561
+
562
+ Every required `OllamaModelName` matches:
563
+
564
+ ```text
565
+ [A-Za-z0-9][A-Za-z0-9._:/-]{0,255}
566
+ ```
567
+
568
+ ### Ollama show options
569
+
570
+ `Arcane.ollama.show(model, options)` accepts `OllamaShowOptions`:
571
+
572
+ | Field | Type | Required | Constraints / default | Description |
573
+ |---|---|---:|---|---|
574
+ | `verbose` | `boolean` | No | Provider default | Requests verbose metadata. |
575
+
576
+ The wrapper supplies the validated `model` field.
577
+
578
+ ### Ollama generate request
579
+
580
+ | Field | Type | Required | Constraints / default | Description |
581
+ |---|---|---:|---|---|
582
+ | `model` | [`OllamaModelName`](#ollama-model-name) | Yes | - | Model to run. |
583
+ | `prompt` | `string` | Provider | - | Generation prompt. |
584
+ | `suffix` | `string` | No | Provider-native | Text after the generated insertion. |
585
+ | `images` | `array` | No | Provider-native base64 values | Multimodal input. |
586
+ | `format` | JSON value | No | Text, JSON, or schema format | Output format. |
587
+ | `options` | object | No | Provider-native; `num_ctx` is 1,024-262,144 when supplied | Runtime options. |
588
+ | `system`, `template` | `string` | No | Provider-native | Prompt controls. |
589
+ | `context` | `array` | No | Provider-native | Legacy context tokens. |
590
+ | `raw` | `boolean` | No | Provider-native | Raw prompt mode. |
591
+ | `keep_alive` | `string \| number` | No | Provider-native | Residency. |
592
+ | `think`, `logprobs`, `top_logprobs` | JSON value | No | Provider-native | Reasoning/log-probability controls. |
593
+
594
+ See [Ollama's generate API](https://docs.ollama.com/api/generate).
595
+
596
+ ### Ollama chat request
597
+
598
+ | Field | Type | Required | Constraints / default | Description |
599
+ |---|---|---:|---|---|
600
+ | `model` | [`OllamaModelName`](#ollama-model-name) | Yes | - | Model to run. |
601
+ | `messages` | `array` | Provider | Provider-native records | Conversation. |
602
+ | `tools` | `array` | No | Provider-native | Tool definitions. |
603
+ | `format` | JSON value | No | Provider-native | Output format or schema. |
604
+ | `options` | object | No | Provider-native; `num_ctx` is 1,024-262,144 when supplied | Runtime options. |
605
+ | `keep_alive` | `string \| number` | No | Provider-native | Residency. |
606
+ | `think`, `logprobs`, `top_logprobs` | JSON value | No | Provider-native | Reasoning/log-probability controls. |
607
+
608
+ See [Ollama's chat API](https://docs.ollama.com/api/chat).
609
+
610
+ ### Ollama embed request
611
+
612
+ | Field | Type | Required | Constraints / default | Description |
613
+ |---|---|---:|---|---|
614
+ | `model` | [`OllamaModelName`](#ollama-model-name) | Yes | - | Embedding model. |
615
+ | `input` | `string \| array` | Provider | Provider-native | Text or batch to embed. |
616
+ | `truncate` | `boolean` | No | Provider-native | Allow truncation. |
617
+ | `dimensions` | `integer` | No | Provider-native | Embedding dimensions. |
618
+ | `keep_alive` | `string \| number` | No | Provider-native | Residency. |
619
+ | `options` | object | No | Provider-native; `num_ctx` is 1,024-262,144 when supplied | Runtime options. |
620
+
621
+ See [Ollama's embed API](https://docs.ollama.com/api/embed).
622
+
623
+ ### Ollama pull options
624
+
625
+ `Arcane.ollama.pull(model, options, streamOptions)` accepts:
626
+
627
+ | Field | Type | Required | Constraints / default | Description |
628
+ |---|---|---:|---|---|
629
+ | `insecure` | `boolean` | No | Provider-native | Insecure-registry control. |
630
+
631
+ The raw application call always rejects; see
632
+ [Raw Ollama management restrictions](#raw-ollama-management-restrictions).
633
+
634
+ ### Ollama push options
635
+
636
+ `Arcane.ollama.push(model, options, streamOptions)` accepts:
637
+
638
+ | Field | Type | Required | Constraints / default | Description |
639
+ |---|---|---:|---|---|
640
+ | `insecure` | `boolean` | No | Provider-native | Insecure-registry control. |
641
+
642
+ Push is allowed only for a model authorized by verified package policy.
643
+
644
+ ### Ollama create request
645
+
646
+ | Field | Type | Required | Constraints / default | Description |
647
+ |---|---|---:|---|---|
648
+ | `model` | [`OllamaModelName`](#ollama-model-name) | Yes | - | Alias to create. |
649
+ | `from` | [`OllamaModelName`](#ollama-model-name) | Conditional | Required by Arcane's managed verified workflow | Base model. |
650
+ | `files`, `adapters` | object | No | Provider-native; forbidden by Arcane's managed path | File/adapter mappings. |
651
+ | `template`, `system` | `string` | No | Provider-native | Stored prompt configuration. |
652
+ | `license` | `string \| array` | No | Provider-native | License text. |
653
+ | `parameters` | object | No | Provider-native | Model parameters. |
654
+ | `messages` | `array` | No | Provider-native | Stored messages. |
655
+ | `quantize` | `string` | No | Provider-native | Quantization request. |
656
+
657
+ Arcane permits creation only when alias, base, SYSTEM text, and parameters
658
+ exactly match the package-owned verified definition. Reserved Arcane and
659
+ rollback aliases reject. See [Ollama's create API](https://docs.ollama.com/api/create).
660
+
661
+ ### Ollama stream controls
662
+
663
+ Generate, chat, pull, push, and create accept `OllamaStreamControls` in the
664
+ document; these controls are not sent as provider request fields.
665
+
666
+ | Field | Type | Required | Constraints / default | Description |
667
+ |---|---|---:|---|---|
668
+ | `onChunk` | [`OllamaChunkCallback`](#ollama-chunk-callback) | No | - | Receives provider-native chunks. |
669
+ | `signal` | `AbortSignal` | No | Genuine signal object | Stops renderer observation and sends a best-effort host cancellation control. Whether host work stops depends on the method. |
670
+ | `timeoutMs` | `number` | No | Callers must supply a positive finite number; method default otherwise | Renderer request timeout. The current wrapper coerces this value, so do not depend on acceptance of another type. |
671
+
672
+ Callers must not send internal `stream` or `streamId`; the wrapper creates them.
673
+
674
+ ### Ollama chunk callback
675
+
676
+ An `OllamaChunkCallback` is called as `onChunk(chunk, metadata)`. `chunk` is a
677
+ provider-native JSON object. `metadata` is `{operation, streamId}`. A callback
678
+ may be passed directly in place of `OllamaStreamControls`.
679
+
680
+ ### Ollama provider responses
681
+
682
+ Direct Ollama methods return bounded provider-native envelopes. Arcane does not
683
+ normalize their nested fields into the provider-neutral entities above. Core
684
+ requires valid JSON, caps a response at 12 MiB, parses newline-delimited stream
685
+ data, and resolves a stream with its final provider chunk.
686
+
687
+ Fields can change with the installed Ollama version. Use the official
688
+ [Ollama API reference](https://docs.ollama.com/api/introduction) for the
689
+ provider response entities.
690
+
691
+ - `version()` returns the version envelope.
692
+ - `models()` and `list()` return the tags envelope, not `model[]`.
693
+ - `running()` returns the running-model envelope, not `model[]`.
694
+ - `show`, `generate`, `chat`, `embed`, `push`, `create`, and `delete` return
695
+ their corresponding provider-native envelope.
696
+
697
+ ### Raw Ollama management restrictions
698
+
699
+ `Arcane.ollama.pull()` and `Arcane.ollama.copy()` always reject and therefore
700
+ return `Promise<never>` to an application. A raw pull lacks integrity-bound
701
+ pre-download evidence; the managed lifecycle owns registry/GGUF preflight and
702
+ native admission. Raw alias copy is reserved to the managed selection workflow.
703
+
704
+ `push`, `create`, and `delete` require verified package policy and reject
705
+ reserved aliases. Unverified-model mode is inference-only and never pulls,
706
+ creates, copies, pushes, deletes, or repairs a model.
707
+
708
+ ## Ollama selection and settings
709
+
710
+ ### Arcane model preference
711
+
712
+ `Arcane.ollama.select(preference)` accepts `ArcaneModelPreference`:
713
+
714
+ | Value | Meaning |
715
+ |---|---|
716
+ | `"auto"` | Try the bounded automatic candidate sequence. |
717
+ | `"3b"`, `"8b"`, `"12b"`, `"20b"`, `"120b"` | Explicit managed Arcane model size. |
718
+
719
+ The value is a preference enum, not an arbitrary model name.
720
+
721
+ ### Arcane model selection
722
+
723
+ `Arcane.ollama.selection()` and `settings()` return `ArcaneModelSelection`.
724
+
725
+ | Field | Type | Required | Constraints / default | Description |
726
+ |---|---|---:|---|---|
727
+ | `preference` | [`ArcaneModelPreference`](#arcane-model-preference) | Yes | - | Saved preference. |
728
+ | `recommendedVariant`, `effectiveVariant` | `string` | Yes | Managed variants | Recommended and resolved sizes. |
729
+ | `model`, `alias` | `string` | Yes | - | Variant model and stable managed alias. |
730
+ | `activeVariant` | `string \| null` | Yes | Managed variant | Persisted active state. |
731
+ | `defaultModel` | [`OllamaModelName`](#ollama-model-name) | Yes | - | Default inference model. |
732
+ | `bootLoad` | `boolean` | Yes | - | Load during managed startup. |
733
+ | `bootKeepAlive` | `"5m" \| "30m" \| "1h" \| "24h" \| "-1"` | Yes | - | Boot residency. |
734
+ | `contextLength` | `integer` | Yes | `0` or 1,024-262,144; `0` is Automatic | Saved context. |
735
+ | `provider` | `"ollama" \| "openai"` | Yes | - | Saved provider. |
736
+ | `openAIModel` | `string` | Yes | - | Saved OpenAI model. |
737
+ | `responseLength` | `"low" \| "medium" \| "high"` | Yes | - | Response target. |
738
+ | `openAIConfigured` | `boolean` | Yes | - | Protected credential exists. |
739
+ | `gpu` | object | Yes | Bounded diagnostic snapshot | Accelerator evidence. |
740
+ | `recommendationPending` | `boolean` | Yes | - | Automatic selection awaits persisted admission. |
741
+
742
+ `gpu` contains `devices` (at most 16 `{name, memoryBytes}` records),
743
+ `totalMemoryBytes`, `largestMemoryBytes`, `memoryReliable`, and `source`.
744
+
745
+ ### Arcane model selection result
746
+
747
+ A successful `select()` returns `ArcaneModelSelectionResult` plus
748
+ [`ArcaneOperation`](#arcane-operation).
749
+
750
+ | Field | Type | Required | Constraints / default | Description |
751
+ |---|---|---:|---|---|
752
+ | `model`, `alias`, `variant`, `preference`, `recommendedVariant` | `string` | Yes | Managed values | Selected model identity. |
753
+ | `created`, `aliasChanged` | `boolean` | Yes | - | Mutation effects. |
754
+ | `baseModel` | `string` | Yes | - | Verified base. |
755
+ | `modelsRoot` | `string \| null` | Yes | Host path | Model store. |
756
+ | `gpu`, `evidence` | object | Yes | Bounded diagnostics | Native and definition evidence. |
757
+ | `compatibility` | [`ModelResourceAdmission`](#model-resource-admission) | Yes | `admitted:true` | Final admission. |
758
+ | `recommendationDegraded` | `boolean` | No | Automatic only | Smaller capacity candidate selected. |
759
+ | `candidateFailures` | `array` | No | Automatic only | Earlier bounded failures. |
760
+ | `rollbackSnapshotRetained` | `boolean` | Yes | - | A recovery snapshot remains because cleanup could not be proven. |
761
+ | `recoveryAlias` | `string \| null` | Yes | Reserved alias when retained | Alias an administrator can use for recovery. |
762
+ | `operation` | [`ArcaneOperation`](#arcane-operation) | Yes | Completed | Selection operation. |
763
+
764
+ ### Arcane AI settings input
765
+
766
+ `Arcane.ollama.saveSettings(settings)` reads only runtime-owned fields. Unknown
767
+ keys, including stale provider/model preference fields from an old screen, are
768
+ ignored so they cannot overwrite newer provider selection.
769
+
770
+ | Field | Type | Required | Constraints / default | Description |
771
+ |---|---|---:|---|---|
772
+ | `defaultModel` | [`OllamaModelName`](#ollama-model-name) | No | Current value | Default runtime model. |
773
+ | `bootLoad` | `boolean` | No | Current value | Load at managed startup. |
774
+ | `bootKeepAlive` | `"5m" \| "30m" \| "1h" \| "24h" \| "-1"` | No | Current value | Boot residency. |
775
+ | `contextLength` | `integer` | No | `0` or 1,024-262,144 | Runtime context; `0` is Automatic. |
776
+
777
+ Use `select()` for the managed size preference and
778
+ `saveProviderSettings()` for provider, OpenAI model, credential, and response
779
+ length.
780
+
781
+ ### Arcane AI settings result
782
+
783
+ A successful settings save returns `ArcaneAISettingsResult`: the complete
784
+ [`ArcaneModelSelection`](#arcane-model-selection) snapshot after the mutation,
785
+ plus `operation` as an [`ArcaneOperation`](#arcane-operation). It does not return
786
+ the selection-only mutation fields such as `created`, `baseModel`, or
787
+ `aliasChanged`.
788
+
789
+ ### Arcane brain definition
790
+
791
+ `Arcane.ollama.createBrain(definition)` reads `ArcaneBrainDefinition`; unknown
792
+ keys are currently ignored and should not be sent.
793
+
794
+ | Field | Type | Required | Constraints / default | Description |
795
+ |---|---|---:|---|---|
796
+ | `baseModel` | [`OllamaModelName`](#ollama-model-name) | Yes | - | Base model. |
797
+ | `name` | `string` | No | Default `"my-brain"`; normalized to a 1-64 character slug | Brain name. |
798
+ | `contextLength` | `integer` | No | `0` for inherited/automatic; use 1,024-262,144 explicitly | Requested context. |
799
+ | `makeDefault` | `boolean` | No | Default `false` | Make the created model the default. |
800
+
801
+ ### Arcane brain result
802
+
803
+ | Field | Type | Required | Constraints / default | Description |
804
+ |---|---|---:|---|---|
805
+ | `model` | `string` | Yes | `arcane-<slug>:latest` | Created model. |
806
+ | `baseModel` | `string` | Yes | - | Base model. |
807
+ | `defaultModel` | `boolean` | Yes | - | Became the default. |
808
+ | `operation` | [`ArcaneOperation`](#arcane-operation) | Yes | Completed | Creation operation. |
809
+
810
+ ### Ollama service settings state
811
+
812
+ `Arcane.ollama.serviceSettings()` returns a platform-dependent native state.
813
+ Microsoft NT reports effective settings and support state. Callers must
814
+ feature-detect platform-specific fields rather than assume one cross-platform
815
+ exact object.
816
+
817
+ ### Ollama service settings input
818
+
819
+ `Arcane.ollama.saveServiceSettings(settings)` applies defaults to omitted fields;
820
+ send the complete desired `OllamaServiceSettingsInput`. Unknown keys are
821
+ currently ignored and should not be sent.
822
+
823
+ | Field | Type | Required | Constraints / default | Description |
824
+ |---|---|---:|---|---|
825
+ | `contextLength` | `integer` | No | Default `0`; 0-262,144 | Service context. |
826
+ | `keepAlive` | `string` | No | Default `"5m"`; `"-1"`, `"0"`, or 1-9,999 plus `m`/`h` | Residency. |
827
+ | `maxLoadedModels` | `integer` | No | Default `1`; 0-16 | Loaded-model limit. |
828
+ | `numParallel` | `integer` | No | Default `1`; 1-16 | Parallel requests. |
829
+ | `maxQueue` | `integer` | No | Default `512`; 1-4,096 | Queue limit. |
830
+ | `flashAttention` | `boolean` | No | Default `false` | Flash attention. |
831
+ | `kvCacheType` | `"f16" \| "q8_0" \| "q4_0"` | No | Default `"f16"` | K/V-cache format. |
832
+ | `noCloud` | `boolean` | No | Default `true` | Prevent Ollama cloud behavior. |
833
+
834
+ ### Ollama service settings result
835
+
836
+ A successful save returns the platform result plus
837
+ [`ArcaneOperation`](#arcane-operation). Microsoft NT currently reports requested
838
+ and effective settings, support/clamping detail, restart state, and post-change
839
+ health. Require `healthy === true` where that field exists.
840
+
841
+ ## Errors and capability boundaries
842
+
843
+ | Method group | Required authority | Additional restriction |
844
+ |---|---|---|
845
+ | Provider-neutral chat/profile and local status | `ai.inference` | Configured provider; local status is served by desktop Core or an explicitly admitted Android `user-managed-loopback` host, distinguished by `providerMode` and runtime fields. |
846
+ | Raw local inventory | `ai.models.read` | Settings, Shell, and Terminal diagnostics. |
847
+ | Provider settings/OpenAI model catalog | `ai.settings.manage` | Settings only. |
848
+ | `localAI.ensurePlatform()` | `provisioning.manage` | Provisioner type; exclusive. |
849
+ | `localAI.recover()` | `ai.inference` | Approved recovery apps; privileged and exclusive. |
850
+ | `localAI.setParallelRequests()` | `ai.runtime.manage` | Sole registered grantee; desktop Core only; privileged and exclusive. |
851
+ | Speech | `ai.inference` | Requires local speech host. |
852
+ | Raw Ollama reads | `ai.models.read` | Diagnostic apps only. |
853
+ | Raw Ollama inference | `ai.inference` | Exact model is re-admitted. |
854
+ | Ollama mutations | `ai.models.manage` | Verified package policy; raw pull/copy reject. |
855
+ | Runtime/provider/service settings | `ai.settings.manage` | Settings restrictions; service mutation is privileged/exclusive. |
856
+
857
+ Additional invariants:
858
+
859
+ - Raw inventory must not populate an application model selector. Use the
860
+ admitted `Arcane.localAI.status().models.ollama` catalog.
861
+ - Browser runtimes gain no local Ollama authority from the shared API
862
+ vocabulary. Android exposes only its explicitly admitted projection (currently
863
+ `ollama.chat()` for approved applications), not desktop lifecycle or model
864
+ mutation authority.
865
+ - Unverified installed-model inference additionally requires
866
+ `ai.models.unverified.inference` and remains inference-only.
867
+ - Arcane never silently changes from Ollama to OpenAI after local discovery or
868
+ admission failure.
869
+ - Provider credentials are never returned to renderers.
870
+ - Status, admission, progress, registry evidence, and model records are
871
+ observations, not grants or reusable authorization.
872
+ - Core rechecks current package policy, model identity, and resources at the
873
+ operation boundary.