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,1909 @@
1
+ # Arcane API AI and Ollama guides
2
+
3
+ These guides distinguish provider-neutral AI from direct Ollama access and from
4
+ Arcane-managed lifecycle operations. Feature-detect the method, then use
5
+ `Arcane.capabilities.list()` when an application must explain why a method is
6
+ unavailable. A method name in the shared JavaScript vocabulary is not itself a
7
+ grant.
8
+
9
+ Rejected calls use `Arcane.Error`. Branch on `code`, and present `message` and
10
+ `resolution` to the user; do not parse human-readable messages as protocol
11
+ values. Provider credentials, operation credentials, admission snapshots, and
12
+ model inventory must not be logged or treated as reusable authorization.
13
+
14
+ The complete request and result entities are defined in the
15
+ [Arcane AI contracts](../../arcane-ai-contracts.md). Managed operations emit
16
+ the standard [Arcane operation events](../../arcane-events.md#event-inventory).
17
+
18
+ ## Arcane.ai.models()
19
+
20
+ ### Overview
21
+
22
+ `Arcane.ai.models()` reads normalized installed-model diagnostics from the
23
+ Arcane-managed Ollama service. Use it in diagnostic UI, not to populate an
24
+ application model selector. Application inference choices must come from the
25
+ admitted `Arcane.localAI.status().models.ollama` catalog.
26
+
27
+ ### Parameters
28
+
29
+ The method takes no arguments.
30
+
31
+ ### Return value
32
+
33
+ It resolves to `LocalAIInventory`: `{provider: "arcane-ollama", models}`. The
34
+ bounded `models` array has at most 512 records with `name`, `modifiedAt`,
35
+ `sizeBytes`, `digest`, `family`, `parameterSize`, and `quantization` fields.
36
+
37
+ ### Availability
38
+
39
+ This is a desktop Core diagnostic API. It requires `ai.models.read` and is
40
+ admitted only to Settings, Shell, and Terminal. Browser previews and the
41
+ current Android projection do not expose it.
42
+
43
+ ### Errors and recovery
44
+
45
+ An unavailable or malformed local provider can reject with a local-Ollama
46
+ request or `LOCAL_OLLAMA_INVALID_RESPONSE` error. Recheck service health before
47
+ retrying. `METHOD_NOT_ALLOWED` requires the correct admitted diagnostic app;
48
+ retrying from another app does not add authority.
49
+
50
+ ### Streaming, cancellation, and events
51
+
52
+ This is one non-streaming inventory read. It emits no method event and exposes
53
+ no per-call `AbortSignal`. The renderer's ordinary request timeout or page
54
+ teardown can stop waiting without promising to cancel host work.
55
+
56
+ ### Example
57
+
58
+ ```javascript
59
+ const inventory = await globalThis.Arcane.ai.models();
60
+
61
+ for (const model of inventory.models) {
62
+ console.info(model.name, model.parameterSize ?? 'unknown size');
63
+ }
64
+ ```
65
+ ## Arcane.ai.chat()
66
+
67
+ ### Overview
68
+
69
+ `Arcane.ai.chat(request)` sends one non-streaming chat request through the
70
+ configured Ollama or OpenAI provider and normalizes the result. Prefer it when
71
+ application code should remain provider-neutral. Bind a request to the profile
72
+ you presented by sending `expectedProvider`; Arcane then rejects a concurrent
73
+ provider change instead of silently switching providers.
74
+
75
+ ### Parameters
76
+
77
+ `request` is a closed `AIChatRequest`. `messages` is required and contains 1-128
78
+ exact `{role, content}` records. Roles are `system`, `user`, or `assistant`;
79
+ each content string is nonempty and at most 131,072 characters, and combined
80
+ content is at most 512 KiB. Portable optional fields are `expectedProvider` and
81
+ `format` (`"json"`, `""`, or `null`). `model`, `options`, `tools`,
82
+ `keep_alive`, `think`, `logprobs`, and `top_logprobs` are Ollama-only controls.
83
+ An omitted local model uses the saved default; OpenAI always uses the saved,
84
+ account-validated model.
85
+
86
+ ### Return value
87
+
88
+ It resolves to normalized `AIChatResult`: `provider`, `model`, an assistant
89
+ `message`, `done`, `doneReason`, `promptEvalCount`, and `evalCount`. Ollama can
90
+ also supply bounded `message.thinking` and `message.toolCalls`. Response content
91
+ and thinking are each retained up to 4 MiB.
92
+
93
+ ### Availability
94
+
95
+ The current public method requires `ai.inference` on desktop Core. It can use
96
+ the selected local Ollama service or protected OpenAI credential. The current
97
+ Android projection exposes direct `Arcane.ollama.chat()`, not this
98
+ provider-neutral method.
99
+
100
+ ### Errors and recovery
101
+
102
+ Correct invalid request, message, model, format, or context errors before
103
+ retrying. `AI_PROVIDER_CHANGED` means refresh `Arcane.ai.profile()` and let the
104
+ user confirm the new provider. OpenAI can reject with
105
+ `OPENAI_NOT_CONFIGURED`, `OPENAI_MODEL_REQUIRED`,
106
+ `OPENAI_MODEL_UNAVAILABLE`, network, bounded-response, or invalid-response
107
+ errors. Local model admission errors require a currently runnable admitted
108
+ model or the managed lifecycle; Arcane never falls back to another provider.
109
+
110
+ ### Streaming, cancellation, and events
111
+
112
+ This API resolves one normalized result and emits no chunk event. The wrapper
113
+ uses a 130-second renderer timeout and does not expose a per-call signal.
114
+ Desktop Core can cooperatively cancel the underlying method when it receives a
115
+ host control frame, including page teardown, but timeout or teardown should
116
+ still be treated as an unknown completion boundary rather than a retry token.
117
+
118
+ ### Example
119
+
120
+ ```javascript
121
+ const arcane = globalThis.Arcane;
122
+ const profile = await arcane.ai.profile();
123
+ const result = await arcane.ai.chat({
124
+ expectedProvider: profile.provider,
125
+ messages: [
126
+ {role: 'system', content: 'Answer briefly and accurately.'},
127
+ {role: 'user', content: 'Explain the current model in one sentence.'}
128
+ ]
129
+ });
130
+
131
+ console.info(result.message.content);
132
+ ```
133
+
134
+ ## Arcane.ai.profile()
135
+
136
+ ### Overview
137
+
138
+ `Arcane.ai.profile()` returns the effective provider-neutral AI selection. Use
139
+ it to label chat UI and to bind `Arcane.ai.chat()` with `expectedProvider`; it
140
+ is not a settings mutation API.
141
+
142
+ ### Parameters
143
+
144
+ The method takes no arguments.
145
+
146
+ ### Return value
147
+
148
+ It resolves to `AIProfile` with `provider` (`"ollama"` or `"openai"`),
149
+ `model`, `configured`, `local`, and `responseLength` (`"low"`, `"medium"`, or
150
+ `"high"`). An OpenAI profile resolves only after Arcane proves a protected
151
+ credential exists and the configured model is available to that account.
152
+
153
+ ### Availability
154
+
155
+ This method requires `ai.inference` on desktop Core. The Ollama branch is local;
156
+ the OpenAI branch performs a protected account-model network request. The
157
+ current Android projection does not expose this method.
158
+
159
+ ### Errors and recovery
160
+
161
+ For OpenAI, `OPENAI_NOT_CONFIGURED`, `OPENAI_MODEL_REQUIRED`, or
162
+ `OPENAI_MODEL_UNAVAILABLE` requires Settings to repair the credential or model.
163
+ Surface network and bounded-response failures as temporary provider failures;
164
+ do not switch providers automatically.
165
+
166
+ ### Streaming, cancellation, and events
167
+
168
+ This is a non-streaming snapshot and emits no method event. It has no per-call
169
+ signal. A profile can become stale immediately, so bind consequential chat
170
+ requests with `expectedProvider`.
171
+
172
+ ### Example
173
+
174
+ ```javascript
175
+ const profile = await globalThis.Arcane.ai.profile();
176
+ const locationLabel = profile.local ? 'On this device' : 'Remote provider';
177
+
178
+ console.info(profile.model, locationLabel, profile.responseLength);
179
+ ```
180
+
181
+ ## Arcane.ai.providerSettings()
182
+
183
+ ### Overview
184
+
185
+ `Arcane.ai.providerSettings()` reads credential-free provider settings for the
186
+ Settings application. Use it to initialize provider controls; use
187
+ `Arcane.ai.profile()` in ordinary inference UI.
188
+
189
+ ### Parameters
190
+
191
+ The method takes no arguments.
192
+
193
+ ### Return value
194
+
195
+ It resolves to `{provider, openAIModel, openAIConfigured, responseLength}`.
196
+ `openAIConfigured` reports only whether protected credential material exists.
197
+ The credential is never returned, and this read does not live-validate the
198
+ account or configured model.
199
+
200
+ ### Availability
201
+
202
+ This is a desktop Core Settings-only API requiring `ai.settings.manage`.
203
+ Browser previews, other apps, and the current Android projection cannot read
204
+ it.
205
+
206
+ ### Errors and recovery
207
+
208
+ `METHOD_NOT_ALLOWED` requires the admitted Settings application and cannot be
209
+ recovered by retry. Transport or protected-store failures should leave the
210
+ existing UI state uncommitted and offer a later retry.
211
+
212
+ ### Streaming, cancellation, and events
213
+
214
+ This is a non-streaming read with no method event or exposed signal. Treat its
215
+ result as a snapshot, especially before a subsequent save.
216
+
217
+ ### Example
218
+
219
+ ```javascript
220
+ const settings = await globalThis.Arcane.ai.providerSettings();
221
+
222
+ console.info({
223
+ provider: settings.provider,
224
+ model: settings.openAIModel,
225
+ credentialPresent: settings.openAIConfigured,
226
+ responseLength: settings.responseLength
227
+ });
228
+ ```
229
+
230
+ ## Arcane.ai.saveProviderSettings()
231
+
232
+ ### Overview
233
+
234
+ `Arcane.ai.saveProviderSettings(settings)` applies a provider-settings patch.
235
+ Use it only from Settings after explicit user intent. Arcane protects OpenAI
236
+ credentials and attempts to roll back credential and settings changes together
237
+ when a save fails.
238
+
239
+ ### Parameters
240
+
241
+ The patch can contain `provider`, `openAIModel`, `responseLength`, `token`, and
242
+ `removeToken`; omitted keys preserve current values. `provider` is `"ollama"`
243
+ or `"openai"`. `openAIModel` is 1-128 characters matching
244
+ `[A-Za-z0-9][A-Za-z0-9._:-]{0,127}`. `responseLength` is `"low"`, `"medium"`,
245
+ or `"high"`. A replacement `token` is trimmed, begins with `sk-`, and is
246
+ 20-512 characters. Only `removeToken: true` requests deletion, and a supplied
247
+ token becomes the final credential. Arcane performs account-model validation
248
+ when OpenAI is selected or a replacement token is supplied.
249
+
250
+ ### Return value
251
+
252
+ It resolves to the credential-free settings shape
253
+ `{provider, openAIModel, openAIConfigured, responseLength}` after persistence.
254
+
255
+ ### Availability
256
+
257
+ This is an exclusive desktop Core mutation requiring `ai.settings.manage` and
258
+ the Settings app identity. OpenAI validation uses the network and protected
259
+ credential store. It is not projected to Android.
260
+
261
+ ### Errors and recovery
262
+
263
+ Correct `INVALID_AI_PROVIDER_SETTINGS`, provider, model, response-length, or
264
+ token errors before retrying. OpenAI account/model errors require a valid
265
+ credential and accessible model. On `CREDENTIAL_STORE_UNAVAILABLE`, leave the
266
+ prior settings in place. `CREDENTIAL_ROLLBACK_FAILED` requires diagnostics and
267
+ manual Settings review before another mutation. Never log a supplied token.
268
+
269
+ ### Streaming, cancellation, and events
270
+
271
+ The method does not stream or emit operation events. The wrapper waits up to
272
+ 130 seconds and exposes no signal. Core does not cooperatively cancel this
273
+ mutation, so closing the page or timing out can stop observation while the save
274
+ continues; read `providerSettings()` before deciding whether to retry.
275
+
276
+ ### Example
277
+
278
+ This credential-free example selects local inference. Read a new OpenAI token
279
+ from a protected user input at call time rather than embedding it in source.
280
+
281
+ ```javascript
282
+ document.querySelector('#confirm-provider-settings')?.addEventListener(
283
+ 'click',
284
+ async function handleConfirmedProviderSettings() {
285
+ const saved = await globalThis.Arcane.ai.saveProviderSettings({
286
+ provider: 'ollama',
287
+ responseLength: 'medium'
288
+ });
289
+ console.info(saved.provider, saved.responseLength);
290
+ }
291
+ );
292
+ ```
293
+
294
+ ## Arcane.ai.providerModels()
295
+
296
+ ### Overview
297
+
298
+ `Arcane.ai.providerModels()` lists OpenAI model identifiers accessible to the
299
+ stored credential. Use it to populate the Settings model control, not to list
300
+ local Ollama models.
301
+
302
+ ### Parameters
303
+
304
+ The method takes no arguments.
305
+
306
+ ### Return value
307
+
308
+ It resolves to `{provider: "openai", models}`, where `models` is a sorted array
309
+ of bounded account-accessible identifiers.
310
+
311
+ ### Availability
312
+
313
+ This is a desktop Core, Settings-only method requiring `ai.settings.manage`.
314
+ It performs one protected OpenAI model-list network request and requires a
315
+ stored credential even when Ollama is currently selected. Android does not
316
+ project it.
317
+
318
+ ### Errors and recovery
319
+
320
+ `OPENAI_NOT_CONFIGURED` requires the user to save a credential. Provider
321
+ unavailable, request-failed, response-too-large, or invalid-response errors are
322
+ not evidence that a previously saved model should be deleted; keep the current
323
+ choice and offer a later retry.
324
+
325
+ ### Streaming, cancellation, and events
326
+
327
+ This is one non-streaming network read with no method event or per-call signal.
328
+ The wrapper timeout is 130 seconds. Avoid issuing a request for every render or
329
+ keystroke; refresh it as one owned Settings task.
330
+
331
+ ### Example
332
+
333
+ ```javascript
334
+ const catalog = await globalThis.Arcane.ai.providerModels();
335
+
336
+ for (const modelId of catalog.models) {
337
+ console.info(modelId);
338
+ }
339
+ ```
340
+
341
+ ## Arcane.localAI.status()
342
+
343
+ ### Overview
344
+
345
+ `Arcane.localAI.status()` discovers currently admitted local inference and
346
+ speech choices. Use its `models` catalogs for application selectors and its
347
+ provider-local status fields for recovery UI. The snapshot is evidence, not a
348
+ grant; Core rechecks policy, identity, and resources at inference time.
349
+
350
+ ### Parameters
351
+
352
+ The method takes no arguments. Core accepts only the empty request generated by
353
+ the wrapper. Concurrent callers in one Core process can share the active
354
+ discovery, so reuse one application-owned refresh instead of polling from each
355
+ component.
356
+
357
+ ### Return value
358
+
359
+ It resolves to schema-version 2 status with `runtime`, `policy`, `ollama`,
360
+ `admission`, `speech`, and `models: {ollama, speech, transcription}`. Desktop
361
+ Core reports native resource admission. Admitted Android returns
362
+ `providerMode: "user-managed-loopback"` and a bounded package-policy catalog;
363
+ its lifecycle remains user-managed and native desktop admission is not claimed.
364
+ Provider discovery failures normally resolve as local `available`,
365
+ `errorCode`, and empty-catalog state rather than rejecting the whole snapshot.
366
+
367
+ ### Availability
368
+
369
+ The method requires `ai.inference`. Desktop Core admits it according to package
370
+ policy. Android projects it only to explicitly admitted application identities,
371
+ using fixed host-owned loopback providers. A browser preview has no local-AI
372
+ authority.
373
+
374
+ ### Errors and recovery
375
+
376
+ An invalid request or package-policy/capability mismatch can reject. Otherwise,
377
+ branch on the returned service-local error codes. Refresh after a documented
378
+ recovery action; do not interpret a transient unavailable service as permission
379
+ to switch providers or mutate models.
380
+
381
+ ### Streaming, cancellation, and events
382
+
383
+ Status is a non-streaming snapshot and emits no method event. The wrapper waits
384
+ up to 15 seconds and exposes no signal. Core discovery is not cooperatively
385
+ cancellable through this method; keep refreshes owned and avoid overlapping
386
+ poll loops.
387
+
388
+ ### Example
389
+
390
+ ```javascript
391
+ const status = await globalThis.Arcane.localAI.status();
392
+ const runnableModels = status.models.ollama.filter(
393
+ function selectRunnableLocalModel(model) {
394
+ return model.runnable === true;
395
+ }
396
+ );
397
+
398
+ console.info(status.runtime.kind, runnableModels.length);
399
+ ```
400
+
401
+ ## Arcane.localAI.ensurePlatform()
402
+
403
+ ### Overview
404
+
405
+ `Arcane.localAI.ensurePlatform()` performs the Provisioner's exclusive
406
+ post-install AI reconciliation. It verifies the current provider settings,
407
+ ensures or repairs the selected verified local model when needed, applies
408
+ resource admission, and optionally loads it. Do not use it as an ordinary app
409
+ readiness probe; use `localAI.status()` instead.
410
+
411
+ ### Parameters
412
+
413
+ The method takes no arguments. It snapshots the current AI settings and retries
414
+ its plan up to three times when they change concurrently.
415
+
416
+ ### Return value
417
+
418
+ Every result includes a completed `ArcaneOperation`. The OpenAI branch reports
419
+ `local.available: false`, reason `"openai-selected"`, a configured `fallback`,
420
+ and no local load. The local branch reports the selected model, alias, variant,
421
+ final compatibility, bounded automatic-candidate failures, no fallback, and
422
+ the managed load result.
423
+
424
+ ### Availability
425
+
426
+ This is a desktop Core, Provisioner-type method requiring
427
+ `provisioning.manage`. It is an exclusive mutation and is not in the Android
428
+ projection.
429
+
430
+ ### Errors and recovery
431
+
432
+ Provider configuration, verified-model, registry, native-admission,
433
+ installation, and load failures preserve their stable Arcane codes and
434
+ resolutions. `ARCANE_AI_PROFILE_CHANGED` means settings changed during three
435
+ plans; refresh settings and let the user restart reconciliation. Arcane does
436
+ not silently select OpenAI after local failure.
437
+
438
+ ### Streaming, cancellation, and events
439
+
440
+ Subscribe before calling if the Provisioner shows progress. The operation emits
441
+ `operation.started`, `operation.log`, `operation.progress`,
442
+ `operation.completed`, or `operation.failed` data keyed by operation ID. The
443
+ wrapper uses the long-operation timeout and exposes no signal; Core does not
444
+ cooperatively cancel this workflow, so page teardown is not rollback.
445
+
446
+ ### Example
447
+
448
+ Run this only in the admitted Provisioner flow after installation succeeds.
449
+
450
+ ```javascript
451
+ document.querySelector('#confirm-local-ai-reconciliation')?.addEventListener(
452
+ 'click',
453
+ async function handleConfirmedLocalAIReconciliation() {
454
+ const result = await globalThis.Arcane.localAI.ensurePlatform();
455
+ if (result.local.available) {
456
+ console.info('Local AI is ready:', result.local.model);
457
+ } else {
458
+ console.info('Configured provider:', result.fallback.provider);
459
+ }
460
+ }
461
+ );
462
+ ```
463
+
464
+ ## Arcane.localAI.recover()
465
+
466
+ ### Overview
467
+
468
+ `Arcane.localAI.recover(request)` starts and verifies existing approved
469
+ Arcane-managed local services. It does not install, replace, stop, or silently
470
+ reconfigure a service. Use it only from the admitted recovery journey after
471
+ status identifies a recoverable service outage.
472
+
473
+ ### Parameters
474
+
475
+ `request` is exactly `{services}`. `services` is a nonempty, duplicate-free
476
+ subset of `"ollama"` and `"speech"`; the result uses canonical Ollama-then-
477
+ speech order.
478
+
479
+ ### Return value
480
+
481
+ It resolves to `{ready: true, services, operation}`. Each service record is
482
+ exactly `{id, serviceName, endpoint, state: "running", ready: true, started}`
483
+ and the completed operation is the privileged recovery receipt.
484
+
485
+ ### Availability
486
+
487
+ This is a privileged, exclusive Core method for explicitly admitted recovery
488
+ application identities with `ai.inference`. The managed recovery adapter is
489
+ currently available on Microsoft NT. Linux reports recovery as unsupported,
490
+ and Android owns its local services outside Arcane.
491
+
492
+ ### Errors and recovery
493
+
494
+ Correct `LOCAL_AI_RECOVERY_INPUT_INVALID` before retrying. Unsupported platform,
495
+ missing registration, service configuration, health, elevation, lease, or
496
+ output-contract errors require the resolution on the `Arcane.Error`; do not
497
+ substitute an installer or arbitrary service command from renderer code.
498
+
499
+ ### Streaming, cancellation, and events
500
+
501
+ The workflow emits standard operation lifecycle and progress events. It is not
502
+ streaming and exposes no signal. Core does not cooperatively cancel it, so a
503
+ renderer timeout or page close can leave recovery running; refresh
504
+ `localAI.status()` before any retry.
505
+
506
+ ### Example
507
+
508
+ ```javascript
509
+ document.querySelector('#confirm-local-ai-recovery')?.addEventListener(
510
+ 'click',
511
+ async function handleConfirmedLocalAIRecovery() {
512
+ const result = await globalThis.Arcane.localAI.recover({
513
+ services: ['speech']
514
+ });
515
+ console.info(result.services[0].ready);
516
+ }
517
+ );
518
+ ```
519
+
520
+ ## Arcane.localAI.setParallelRequests()
521
+
522
+ ### Overview
523
+
524
+ `Arcane.localAI.setParallelRequests(request)` calculates and applies the
525
+ machine-wide Ollama parallel-request count for one exact app-owned verified
526
+ model. It can restart Ollama, evict all resident models, and terminate in-flight
527
+ local inference. Use it only in the sole registered application-owned
528
+ administrative flow with clear impact disclosure.
529
+
530
+ ### Parameters
531
+
532
+ `request` is exactly `{model, parallelRequests, contextTokens?}`. `model` is an
533
+ app-owned verified identifier. `parallelRequests` is a nonnegative safe integer:
534
+ `0` requests the maximum currently admitted; a positive request is a ceiling
535
+ that Arcane can clamp down. `contextTokens` is a positive safe integer when
536
+ present and otherwise uses the verified Modelfile value. Native model metadata,
537
+ not an Arcane product ceiling, governs the maximum context.
538
+
539
+ ### Return value
540
+
541
+ The schema-version 1 receipt reports requested, previous, maximum allowed,
542
+ allowed, and effective parallelism; context and native-context evidence;
543
+ clamping, change, restart, health, and load state; evicted models; final
544
+ admission; and a completed operation. Treat capacity evidence as a current
545
+ snapshot, not a future performance promise.
546
+
547
+ ### Availability
548
+
549
+ This is a privileged, exclusive desktop Core method for the sole registered
550
+ owning application identity, requiring `ai.runtime.manage`. Microsoft NT applies
551
+ the setting. Linux returns a 501 manual-systemd error, and Android does not
552
+ expose the method.
553
+
554
+ ### Errors and recovery
555
+
556
+ Input, app-owned-model, verified-policy, admission, capacity, unsupported,
557
+ apply, health, load, and rollback errors are actionable by stable code. Arcane
558
+ attempts to restore the prior count when loading fails after a change. After
559
+ any uncertain completion, refresh status and service settings before another
560
+ mutation.
561
+
562
+ ### Streaming, cancellation, and events
563
+
564
+ The method emits standard operation events but no provider chunks. It has a
565
+ long renderer timeout and no signal, and Core does not cooperatively cancel the
566
+ workflow. A timeout or page close can occur while the service transaction
567
+ continues.
568
+
569
+ ### Example
570
+
571
+ This no-change-oriented example requests the currently active count for a
572
+ verified runnable model; it can still perform verification and loading.
573
+
574
+ ```javascript
575
+ document.querySelector('#confirm-parallel-request-change')?.addEventListener(
576
+ 'click',
577
+ async function handleConfirmedParallelRequestChange() {
578
+ const arcane = globalThis.Arcane;
579
+ const status = await arcane.localAI.status();
580
+ const model = status.models.ollama.find(
581
+ function findVerifiedRunnableModel(candidate) {
582
+ return candidate.verified === true && candidate.runnable === true;
583
+ }
584
+ );
585
+ if (!model) return;
586
+
587
+ const result = await arcane.localAI.setParallelRequests({
588
+ model: model.id,
589
+ parallelRequests: status.ollama.activeParallelRequests
590
+ });
591
+ console.info(result.effectiveParallelRequests);
592
+ }
593
+ );
594
+ ```
595
+
596
+ ## Arcane.speech.status()
597
+
598
+ ### Overview
599
+
600
+ `Arcane.speech.status()` directly checks the fixed local speech service. Use it
601
+ when UI needs current synthesis and transcription readiness. Unlike
602
+ `localAI.status()`, this direct call rejects when the host cannot reach and
603
+ validate the speech health response.
604
+
605
+ ### Parameters
606
+
607
+ The method takes no arguments.
608
+
609
+ ### Return value
610
+
611
+ It resolves to `{ready, synthesisAvailable, transcriptionAvailable, status,
612
+ ttsEngine, sttEngine}`. `ready` is true only when both roles are ready; use the
613
+ role-specific booleans when UI needs only synthesis or transcription.
614
+
615
+ ### Availability
616
+
617
+ The method requires `ai.inference` and a fixed host-owned local speech service.
618
+ It is available on desktop Core and, through the current Android projection, to
619
+ explicitly admitted application identities. Browser previews cannot reach it.
620
+
621
+ ### Errors and recovery
622
+
623
+ `LOCAL_SPEECH_UNAVAILABLE`, request-failed, invalid-response, or
624
+ response-too-large errors mean the direct health contract was not proven.
625
+ Offer the admitted managed recovery journey where available; do not probe or
626
+ start arbitrary loopback services from renderer code.
627
+
628
+ ### Streaming, cancellation, and events
629
+
630
+ This is a non-streaming health read with no method event. The wrapper timeout
631
+ is 10 seconds and no per-call signal is exposed. Core does not cooperatively
632
+ cancel this method; Android also does not expose speech cancellation.
633
+
634
+ ### Example
635
+
636
+ ```javascript
637
+ const status = await globalThis.Arcane.speech.status();
638
+
639
+ console.info({
640
+ synthesis: status.synthesisAvailable,
641
+ transcription: status.transcriptionAvailable
642
+ });
643
+ ```
644
+
645
+ ## Arcane.speech.synthesize()
646
+
647
+ ### Overview
648
+
649
+ `Arcane.speech.synthesize(request)` converts bounded text to local speech. Use
650
+ it only after checking synthesis readiness, and create an audio URL from the
651
+ returned bytes without logging the base64 payload.
652
+
653
+ ### Parameters
654
+
655
+ `request` uses the portable fields `input`, `model`, `voice`,
656
+ `responseFormat`, and `speed`. `input` is required, trimmed, nonempty, and at
657
+ most 4,000 characters. Defaults are `model: "kokoro"`, `voice: "af_heart"`,
658
+ `responseFormat: "opus"`, and `speed: 1`. The voice matches
659
+ `[a-z0-9][a-z0-9_-]{0,63}`, the format is `"opus"` or `"wav"`, and speed is
660
+ 0.5-2 inclusive. Send documented types; do not rely on host coercion of
661
+ off-contract values.
662
+
663
+ ### Return value
664
+
665
+ It resolves to `{audioBase64, contentType}`. The canonical base64 represents
666
+ 1 byte through 6 MiB of audio, and `contentType` is `"audio/ogg"` or
667
+ `"audio/wav"` matching the selected format.
668
+
669
+ ### Availability
670
+
671
+ This method requires `ai.inference` and a ready fixed local speech provider.
672
+ It is available on desktop Core and to explicitly admitted applications through
673
+ the Android projection. Android bounds speech work to one active and one queued
674
+ operation.
675
+
676
+ ### Errors and recovery
677
+
678
+ Correct `INVALID_LOCAL_SPEECH_REQUEST` locally. Unavailable, request-failed,
679
+ response-too-large, or invalid-response errors require a health refresh or
680
+ managed recovery. On Android, `ANDROID_SPEECH_QUEUE_FULL` means wait for the
681
+ owned active operation before retrying.
682
+
683
+ ### Streaming, cancellation, and events
684
+
685
+ Synthesis returns one complete audio result and emits no method event. The
686
+ wrapper timeout is 180 seconds, no signal is exposed, and timeout or page
687
+ teardown does not promise cancellation of Core or Android speech work.
688
+
689
+ ### Example
690
+
691
+ ```javascript
692
+ const result = await globalThis.Arcane.speech.synthesize({
693
+ input: 'Your local speech service is ready.',
694
+ voice: 'af_heart',
695
+ responseFormat: 'opus',
696
+ speed: 1
697
+ });
698
+
699
+ console.info(result.contentType, result.audioBase64.length);
700
+ ```
701
+
702
+ ## Arcane.speech.transcribe()
703
+
704
+ ### Overview
705
+
706
+ `Arcane.speech.transcribe(request)` sends bounded caller-supplied audio bytes,
707
+ labeled as WebM, to the fixed local transcription service. Use it after local
708
+ capture permission and recording have succeeded; the method itself does not
709
+ capture audio or grant microphone permission.
710
+
711
+ ### Parameters
712
+
713
+ `audioBase64` is required canonical base64: at most 8 MiB encoded and 1 byte
714
+ through 6 MiB decoded. `mimeType` defaults to `"audio/webm"`; codec parameters
715
+ may follow, but the base type must be WebM. `model` defaults to
716
+ `"whisper-small"`. Core accepts the bounded Whisper-name pattern while the
717
+ current Android provider requires exactly `"whisper-small"`. The host validates
718
+ the label, encoding, and size; the fixed service decodes the media container.
719
+
720
+ ### Return value
721
+
722
+ It resolves to `{text}` with a trimmed transcript from a response bounded to
723
+ 64 KiB.
724
+
725
+ ### Availability
726
+
727
+ This method requires `ai.inference` and ready local transcription. It is
728
+ available on desktop Core and to explicitly admitted applications through the
729
+ Android projection. Browser capture permission is separate from method
730
+ admission.
731
+
732
+ ### Errors and recovery
733
+
734
+ Correct invalid base64, size, MIME, or model errors before retrying.
735
+ Unavailable, request-failed, response-too-large, and invalid-response errors
736
+ require a status refresh or managed recovery. On Android, wait for owned speech
737
+ work after `ANDROID_SPEECH_QUEUE_FULL`.
738
+
739
+ ### Streaming, cancellation, and events
740
+
741
+ Transcription resolves one complete text result and emits no method event. The
742
+ wrapper timeout is 180 seconds and no signal is exposed. Core and Android do
743
+ not promise cancellation when the renderer stops waiting.
744
+
745
+ ### Example
746
+
747
+ ```javascript
748
+ async function transcribeRecordedWebM(audioBase64) {
749
+ const result = await globalThis.Arcane.speech.transcribe({
750
+ audioBase64: audioBase64,
751
+ mimeType: 'audio/webm',
752
+ model: 'whisper-small'
753
+ });
754
+ return result.text;
755
+ }
756
+ ```
757
+
758
+ ## Arcane.ollama.version()
759
+
760
+ ### Overview
761
+
762
+ `Arcane.ollama.version()` reads the fixed local Ollama provider's version
763
+ envelope. Use it for diagnostics and compatibility display, not as model
764
+ readiness or authorization evidence.
765
+
766
+ ### Parameters
767
+
768
+ The method takes no arguments.
769
+
770
+ ### Return value
771
+
772
+ It resolves to Ollama's provider-native version JSON. Arcane requires valid
773
+ JSON and bounds the response to 12 MiB, but provider fields can vary with the
774
+ installed Ollama version.
775
+
776
+ ### Availability
777
+
778
+ This is a desktop Core diagnostic API requiring `ai.models.read`; it is
779
+ admitted only to Settings, Shell, and Terminal. Core calls the fixed
780
+ `127.0.0.1:11434` provider. The current Android projection and browser previews
781
+ do not expose this method.
782
+
783
+ ### Errors and recovery
784
+
785
+ `LOCAL_OLLAMA_REQUEST_FAILED` covers an unavailable service, HTTP failure, or
786
+ invalid provider response and marks retryable server failures where applicable.
787
+ Refresh service status or use an admitted recovery workflow before retrying.
788
+ `METHOD_NOT_ALLOWED` requires the correct diagnostic app.
789
+
790
+ ### Streaming, cancellation, and events
791
+
792
+ This is a non-streaming read with no method event or exposed signal. The
793
+ provider request has a five-second Core timeout; the renderer also owns its
794
+ outer request timeout.
795
+
796
+ ### Example
797
+
798
+ ```javascript
799
+ const versionInfo = await globalThis.Arcane.ollama.version();
800
+
801
+ console.info(versionInfo.version ?? 'Unknown Ollama version');
802
+ ```
803
+
804
+ ## Arcane.ollama.models()
805
+
806
+ ### Overview
807
+
808
+ `Arcane.ollama.models()` reads Ollama's installed tags envelope. Use it for raw
809
+ diagnostics. It is not the normalized `Arcane.ai.models()` inventory and must
810
+ not populate an application selector; use admitted `localAI.status()` models
811
+ for inference UI.
812
+
813
+ ### Parameters
814
+
815
+ The method takes no arguments.
816
+
817
+ ### Return value
818
+
819
+ It resolves to the bounded provider-native `/api/tags` envelope, usually with
820
+ a `models` array. Nested fields follow the installed Ollama version rather than
821
+ an Arcane-normalized entity contract.
822
+
823
+ ### Availability
824
+
825
+ This desktop Core method requires `ai.models.read` and is limited to Settings,
826
+ Shell, and Terminal. It is not projected to Android or browser previews.
827
+
828
+ ### Errors and recovery
829
+
830
+ Local provider transport, HTTP, invalid-JSON, and bounded-response failures
831
+ reject as Arcane errors. Recheck local service health and retry as one owned
832
+ diagnostic refresh. Do not turn a raw provider record into an authorization or
833
+ verified-model claim.
834
+
835
+ ### Streaming, cancellation, and events
836
+
837
+ This is one non-streaming read with no method event or per-call signal. Core's
838
+ provider timeout is ten seconds.
839
+
840
+ ### Example
841
+
842
+ ```javascript
843
+ const tags = await globalThis.Arcane.ollama.models();
844
+
845
+ for (const model of tags.models ?? []) {
846
+ console.info(model.name ?? model.model ?? 'Unnamed model');
847
+ }
848
+ ```
849
+
850
+ ## Arcane.ollama.list()
851
+
852
+ ### Overview
853
+
854
+ `Arcane.ollama.list()` is a JavaScript alias for
855
+ `Arcane.ollama.models()`. It invokes the same `ollama.models` Core method and
856
+ returns the same raw tags envelope. Prefer one spelling consistently within an
857
+ application.
858
+
859
+ ### Parameters
860
+
861
+ The method takes no arguments.
862
+
863
+ ### Return value
864
+
865
+ It resolves to the bounded provider-native `/api/tags` envelope, not a bare
866
+ model array.
867
+
868
+ ### Availability
869
+
870
+ The alias has exactly the `ollama.models` boundary: desktop Core,
871
+ `ai.models.read`, and Settings, Shell, or Terminal only. There is no distinct
872
+ `ollama.list` capability-policy method and no Android projection.
873
+
874
+ ### Errors and recovery
875
+
876
+ Handle the same local-provider and method-admission errors as
877
+ `Arcane.ollama.models()`. A retry is useful only after service health or
878
+ transport state can have changed.
879
+
880
+ ### Streaming, cancellation, and events
881
+
882
+ This is a non-streaming read with no method event or signal. It does not create
883
+ a second catalog or cache; it is just another wrapper name for the same call.
884
+
885
+ ### Example
886
+
887
+ ```javascript
888
+ const tags = await globalThis.Arcane.ollama.list();
889
+ const installedCount = Array.isArray(tags.models) ? tags.models.length : 0;
890
+
891
+ console.info(installedCount);
892
+ ```
893
+
894
+ ## Arcane.ollama.running()
895
+
896
+ ### Overview
897
+
898
+ `Arcane.ollama.running()` reads Ollama's currently loaded-model envelope. Use
899
+ it for diagnostics such as residency display. It is a momentary provider
900
+ snapshot, not proof that capacity or admission will remain available.
901
+
902
+ ### Parameters
903
+
904
+ The method takes no arguments.
905
+
906
+ ### Return value
907
+
908
+ It resolves to the bounded provider-native `/api/ps` JSON, usually with a
909
+ `models` array. Arcane does not normalize its nested provider fields.
910
+
911
+ ### Availability
912
+
913
+ This is a desktop Core diagnostic read requiring `ai.models.read`, admitted
914
+ only to Settings, Shell, and Terminal. Android and browser previews do not
915
+ expose it.
916
+
917
+ ### Errors and recovery
918
+
919
+ An unavailable provider, failed HTTP request, invalid JSON, or oversized
920
+ response rejects. Refresh local service status before retrying. An empty
921
+ provider array is a valid no-model-loaded state, not an error.
922
+
923
+ ### Streaming, cancellation, and events
924
+
925
+ This method does not stream or emit events and has no signal. Core's provider
926
+ timeout is ten seconds. Models can load or unload immediately after resolution.
927
+
928
+ ### Example
929
+
930
+ ```javascript
931
+ const running = await globalThis.Arcane.ollama.running();
932
+
933
+ for (const model of running.models ?? []) {
934
+ console.info(model.name ?? model.model ?? 'Unnamed loaded model');
935
+ }
936
+ ```
937
+
938
+ ## Arcane.ollama.show()
939
+
940
+ ### Overview
941
+
942
+ `Arcane.ollama.show(model, options?)` reads provider metadata for one installed
943
+ model. Use it for bounded diagnostics and compatibility inspection; returned
944
+ metadata is not verified package provenance or reusable admission evidence.
945
+
946
+ ### Parameters
947
+
948
+ `model` is required and matches
949
+ `[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}`. The optional object has only `verbose`;
950
+ send a Boolean when requesting provider verbose metadata. The wrapper builds
951
+ the top-level `model` field, and Core rejects unknown top-level fields.
952
+
953
+ ### Return value
954
+
955
+ It resolves to Ollama's bounded provider-native `/api/show` envelope. Nested
956
+ metadata, parameters, template, and capability fields depend on the installed
957
+ provider version.
958
+
959
+ ### Availability
960
+
961
+ This desktop Core method requires `ai.models.read` and Settings, Shell, or
962
+ Terminal identity. It is not projected to Android or browser previews.
963
+
964
+ ### Errors and recovery
965
+
966
+ `INVALID_AI_MODEL` requires a valid installed-model identifier.
967
+ `INVALID_OLLAMA_REQUEST`, provider not-found, request, invalid-response, or
968
+ bounded-response errors should be surfaced without upgrading raw metadata into
969
+ a verified-model claim. Refresh inventory before retrying a not-found model.
970
+
971
+ ### Streaming, cancellation, and events
972
+
973
+ This is a non-streaming read with no method event or signal. Core gives the
974
+ provider request 30 seconds.
975
+
976
+ ### Example
977
+
978
+ ```javascript
979
+ const metadata = await globalThis.Arcane.ollama.show('gemma3:latest', {
980
+ verbose: false
981
+ });
982
+
983
+ console.info(metadata.details ?? metadata.model_info ?? {});
984
+ ```
985
+
986
+ ## Arcane.ollama.generate()
987
+
988
+ ### Overview
989
+
990
+ `Arcane.ollama.generate(request, streamOptions?)` calls Ollama's direct generate
991
+ API after Core re-admits the exact model and requested context. Use it only
992
+ when provider-native generation fields or chunks are required; use
993
+ `Arcane.ai.chat()` for provider-neutral application chat.
994
+
995
+ ### Parameters
996
+
997
+ `request` is a closed plain object, encoded to at most 8 MiB. Required `model`
998
+ uses the Ollama name pattern. Supported provider fields are `prompt`, `suffix`,
999
+ `images`, `format`, `options`, `system`, `template`, `context`, `raw`,
1000
+ `keep_alive`, `think`, `logprobs`, and `top_logprobs`. When supplied,
1001
+ `options.num_ctx` is a safe integer from 1,024 through 262,144.
1002
+
1003
+ `streamOptions` can be a named chunk callback or `{onChunk, signal,
1004
+ timeoutMs}`. Pass a genuine `AbortSignal` and a positive finite timeout; callers
1005
+ must not send the wrapper-owned `stream` or `streamId` fields.
1006
+
1007
+ ### Return value
1008
+
1009
+ Without chunk delivery, it resolves to Ollama's bounded provider-native
1010
+ generate envelope. With `onChunk`, the callback receives `(chunk,
1011
+ {operation: "generate", streamId})` for each filtered stream record, and the
1012
+ promise resolves to the final provider chunk.
1013
+
1014
+ ### Availability
1015
+
1016
+ This is a desktop Core method requiring `ai.inference`. Verified app models can
1017
+ be ensured or repaired before final admission. Unverified installed-model
1018
+ inference additionally requires `ai.models.unverified.inference` and remains
1019
+ inference-only. Applications with an isolated-model contract must use their
1020
+ application-owned isolated API. Android does not project direct generate.
1021
+
1022
+ ### Errors and recovery
1023
+
1024
+ Correct invalid request, model, stream, serialization, size, and context errors
1025
+ locally. Model policy, verification, installation, isolated-operation, and
1026
+ resource-admission errors require a currently admitted model or the documented
1027
+ managed workflow. Provider failures reject as local-Ollama request errors;
1028
+ Arcane does not fall back to OpenAI.
1029
+
1030
+ ### Streaming, cancellation, and events
1031
+
1032
+ Chunk delivery is backed by internal `ollama.chunk` events filtered to the
1033
+ wrapper-created stream ID; callers normally use `onChunk`, not a global event
1034
+ subscription. The default timeout is ten minutes. Aborting the supplied signal
1035
+ rejects the renderer promise, sends a cancel control, and desktop Core
1036
+ cooperatively destroys the active provider request. A chunk-callback exception
1037
+ is logged by the event dispatcher; own callback errors explicitly if they must
1038
+ fail application work.
1039
+
1040
+ ### Example
1041
+
1042
+ ```javascript
1043
+ const arcane = globalThis.Arcane;
1044
+ const status = await arcane.localAI.status();
1045
+ const model = status.models.ollama.find(function findRunnableModel(candidate) {
1046
+ return candidate.runnable === true;
1047
+ });
1048
+
1049
+ if (!model) {
1050
+ throw new Error('No admitted local model is currently runnable.');
1051
+ }
1052
+
1053
+ const controller = new AbortController();
1054
+
1055
+ function handleGenerateChunk(chunk, metadata) {
1056
+ console.info(metadata.operation, chunk.done === true ? 'done' : 'working');
1057
+ }
1058
+
1059
+ const finalChunk = await arcane.ollama.generate({
1060
+ model: model.id,
1061
+ prompt: 'Write one short, credential-free greeting.'
1062
+ }, {
1063
+ onChunk: handleGenerateChunk,
1064
+ signal: controller.signal,
1065
+ timeoutMs: 120000
1066
+ });
1067
+
1068
+ console.info(finalChunk.done === true);
1069
+ ```
1070
+
1071
+ ## Arcane.ollama.chat()
1072
+
1073
+ ### Overview
1074
+
1075
+ `Arcane.ollama.chat(request, streamOptions?)` sends a provider-native Ollama
1076
+ chat after the host rechecks package policy, model identity, and current
1077
+ admission. Use it when Ollama-specific messages, tools, options, or streaming
1078
+ are intentional; use `Arcane.ai.chat()` for a normalized provider-neutral
1079
+ result.
1080
+
1081
+ ### Parameters
1082
+
1083
+ On desktop Core, `request` is a closed plain object of at most 8 MiB with
1084
+ required `model` and provider-native `messages`. Optional fields are `tools`,
1085
+ `format`, `options`, `keep_alive`, `think`, `logprobs`, and `top_logprobs`;
1086
+ `options.num_ctx`, when present, is 1,024-262,144. `streamOptions` can be a
1087
+ named callback or `{onChunk, signal, timeoutMs}` and is not forwarded to
1088
+ Ollama.
1089
+
1090
+ Android admits a narrower generated contract for explicitly approved apps: 1-128
1091
+ bounded messages with `system`, `user`, `assistant`, or `tool` roles; bounded
1092
+ `format`, `think`, `tools`, and selected generation options; at most 512 KiB of
1093
+ combined message content and 768 KiB encoded request data. Do not send desktop-
1094
+ only `keep_alive` or log-probability fields when targeting Android.
1095
+
1096
+ ### Return value
1097
+
1098
+ It resolves to the final bounded provider-native chat envelope. With
1099
+ `onChunk`, each callback receives `(chunk, {operation: "chat", streamId})` and
1100
+ the promise resolves to the final provider chunk. Direct provider fields are
1101
+ not normalized into `AIChatResult`.
1102
+
1103
+ ### Availability
1104
+
1105
+ The method requires `ai.inference`. Desktop Core admits it according to package
1106
+ policy and native resource checks. Android projects the bounded user-managed-
1107
+ loopback form only to explicitly approved apps and repeats package-policy/provider
1108
+ inspection before dispatch. Plain browser previews have no Ollama authority.
1109
+
1110
+ ### Errors and recovery
1111
+
1112
+ Correct invalid request, message, option, model, stream, size, or response
1113
+ errors locally. Policy, verified-model, installation, queue, isolated-operation,
1114
+ and capacity errors require a runnable admitted model; never bypass them by
1115
+ calling loopback directly. Android can additionally report queue, timeout,
1116
+ cancel, invalid-provider-response, or response-size errors. No branch silently
1117
+ changes provider.
1118
+
1119
+ ### Streaming, cancellation, and events
1120
+
1121
+ The wrapper filters internal `ollama.chunk` events by its generated stream ID.
1122
+ The default renderer timeout is ten minutes. A supplied signal cancels the
1123
+ renderer request; desktop Core cooperatively destroys its provider request and
1124
+ Android cancels the owned chat task. Store application cleanup for any external
1125
+ controller or UI listener.
1126
+
1127
+ ### Example
1128
+
1129
+ ```javascript
1130
+ const arcane = globalThis.Arcane;
1131
+ const status = await arcane.localAI.status();
1132
+ const model = status.models.ollama.find(function findRunnableChatModel(candidate) {
1133
+ return candidate.runnable === true;
1134
+ });
1135
+
1136
+ if (!model) {
1137
+ throw new Error('No admitted local model is currently runnable.');
1138
+ }
1139
+
1140
+ function handleChatChunk(chunk, metadata) {
1141
+ console.info(metadata.operation, chunk.done === true ? 'done' : 'working');
1142
+ }
1143
+
1144
+ const result = await arcane.ollama.chat({
1145
+ model: model.id,
1146
+ messages: [{role: 'user', content: 'Reply with one short sentence.'}]
1147
+ }, {
1148
+ onChunk: handleChatChunk,
1149
+ timeoutMs: 120000
1150
+ });
1151
+
1152
+ console.info(result.message?.content ?? 'No text returned');
1153
+ ```
1154
+
1155
+ ## Arcane.ollama.embed()
1156
+
1157
+ ### Overview
1158
+
1159
+ `Arcane.ollama.embed(request)` creates provider-native local embeddings after
1160
+ Core re-admits the exact model and requested context. Use it only when an
1161
+ application intentionally owns the Ollama embedding contract and the returned
1162
+ vectors' storage/privacy lifecycle.
1163
+
1164
+ ### Parameters
1165
+
1166
+ `request` is a closed plain object of at most 8 MiB. Required `model` uses the
1167
+ Ollama name pattern. Supported provider fields are `input` (text or a batch),
1168
+ `truncate`, `dimensions`, `keep_alive`, and `options`; when present,
1169
+ `options.num_ctx` is 1,024-262,144. Nested provider-native values are forwarded
1170
+ for Ollama to validate.
1171
+
1172
+ ### Return value
1173
+
1174
+ It resolves to Ollama's bounded provider-native embed envelope, including the
1175
+ provider's vectors and metadata. Arcane does not normalize vector count or
1176
+ dimension into a separate stable entity.
1177
+
1178
+ ### Availability
1179
+
1180
+ This is a desktop Core method requiring `ai.inference`. Verified models can use
1181
+ the managed ensure/repair path before admission. Unverified installed models
1182
+ also require `ai.models.unverified.inference`. Applications with an isolated
1183
+ model contract must use their application-owned API, and Android does not
1184
+ project direct embed.
1185
+
1186
+ ### Errors and recovery
1187
+
1188
+ Correct invalid object, unknown field, model, serialization, request-size, or
1189
+ context errors before retrying. Model-policy, installation, isolation, and
1190
+ resource-admission errors require a currently admitted embedding model.
1191
+ Provider failures remain local-Ollama errors and never trigger remote fallback.
1192
+
1193
+ ### Streaming, cancellation, and events
1194
+
1195
+ The public wrapper does not accept stream controls, a chunk callback, or an
1196
+ `AbortSignal`; it resolves one result and emits no method event. Its renderer
1197
+ timeout is ten minutes. Although the Core RPC boundary can cancel an embed
1198
+ request when a host control arrives, application code has no per-call signal in
1199
+ this API.
1200
+
1201
+ ### Example
1202
+
1203
+ ```javascript
1204
+ async function embedNonSensitiveText(verifiedEmbeddingModel, text) {
1205
+ if (typeof text !== 'string' || text.length === 0) {
1206
+ throw new TypeError('Embedding input must be nonempty text.');
1207
+ }
1208
+ return globalThis.Arcane.ollama.embed({
1209
+ model: verifiedEmbeddingModel,
1210
+ input: text
1211
+ });
1212
+ }
1213
+ ```
1214
+
1215
+ ## Arcane.ollama.pull()
1216
+
1217
+ ### Overview
1218
+
1219
+ `Arcane.ollama.pull(model, options?, streamOptions?)` is intentionally denied to
1220
+ applications. A raw mutable-tag pull lacks integrity-bound pre-download
1221
+ evidence and native resource admission. Use an admitted managed selection or
1222
+ application-model workflow; do not retry the raw method or call Ollama's
1223
+ loopback endpoint directly.
1224
+
1225
+ ### Parameters
1226
+
1227
+ The wrapper accepts a model name, optional `{insecure}`, and optional stream
1228
+ controls. Model names use the 1-256 character Ollama pattern and `insecure`
1229
+ would be provider-native registry control. These arguments do not relax the
1230
+ Core policy denial.
1231
+
1232
+ ### Return value
1233
+
1234
+ For application callers the method returns `Promise<never>`: it rejects before
1235
+ issuing a provider pull and therefore has no success envelope.
1236
+
1237
+ ### Availability
1238
+
1239
+ The vocabulary is present only at desktop Core's `ai.models.manage` boundary,
1240
+ but every admitted application call is denied. Verified-only policy returns
1241
+ `MANAGED_MODEL_WORKFLOW_REQUIRED`; unverified-model policy returns
1242
+ `UNVERIFIED_MODEL_MUTATION_FORBIDDEN`. Android and browser previews do not gain
1243
+ model-management authority.
1244
+
1245
+ ### Errors and recovery
1246
+
1247
+ Both policy errors are terminal for this raw method. Choose a model through
1248
+ `Arcane.ollama.select()` or another package-bound managed workflow that performs
1249
+ registry evidence, integrity verification, and resource admission. Do not
1250
+ weaken transport security with `insecure` as a workaround.
1251
+
1252
+ ### Streaming, cancellation, and events
1253
+
1254
+ Although the wrapper signature accepts stream controls, Core rejects before a
1255
+ provider request, so there are no chunks or operation events to cancel.
1256
+
1257
+ ### Example
1258
+
1259
+ This safe example demonstrates the required denial without starting a download.
1260
+
1261
+ ```javascript
1262
+ try {
1263
+ await globalThis.Arcane.ollama.pull('gemma3:latest');
1264
+ throw new Error('Raw Ollama pull unexpectedly succeeded.');
1265
+ } catch (error) {
1266
+ const expectedCodes = [
1267
+ 'MANAGED_MODEL_WORKFLOW_REQUIRED',
1268
+ 'UNVERIFIED_MODEL_MUTATION_FORBIDDEN'
1269
+ ];
1270
+ if (!expectedCodes.includes(error.code)) {
1271
+ throw error;
1272
+ }
1273
+ console.info('Use the managed Arcane model workflow.');
1274
+ }
1275
+ ```
1276
+
1277
+ ## Arcane.ollama.push()
1278
+
1279
+ ### Overview
1280
+
1281
+ `Arcane.ollama.push(model, options?, streamOptions?)` pushes an exact
1282
+ package-authorized verified model through the local Ollama provider. It can
1283
+ transfer model data to a configured registry. Use it only after explicit user
1284
+ authorization and provider/registry review; ordinary applications should not
1285
+ expose raw model publishing.
1286
+
1287
+ ### Parameters
1288
+
1289
+ `model` is required and must be both a valid Ollama name and an app-owned
1290
+ verified definition. The optional provider object contains only Boolean
1291
+ `insecure`; keep it false unless an approved development registry explicitly
1292
+ requires otherwise. Stream controls can be a named callback or `{onChunk,
1293
+ signal, timeoutMs}` and are not forwarded as provider fields.
1294
+
1295
+ ### Return value
1296
+
1297
+ It resolves to the bounded provider-native push envelope. With a chunk callback,
1298
+ the callback receives `(chunk, {operation: "push", streamId})`, and the promise
1299
+ resolves with the final provider chunk.
1300
+
1301
+ ### Availability
1302
+
1303
+ This is an exclusive desktop Core mutation requiring `ai.models.manage` and an
1304
+ exact verified-only package model. Unverified-model mode is inference-only.
1305
+ Android and browser previews do not expose it.
1306
+
1307
+ ### Errors and recovery
1308
+
1309
+ Invalid request/model errors require correction. Missing verified policy or an
1310
+ unknown app model is not retryable without a new package. Registry/provider
1311
+ failures can be retried only after confirming that a duplicate or partial
1312
+ remote publication is safe. Never place registry credentials in the request or
1313
+ logs.
1314
+
1315
+ ### Streaming, cancellation, and events
1316
+
1317
+ Chunks use wrapper-filtered `ollama.chunk` events. The default renderer timeout
1318
+ is 50 minutes. A supplied signal stops renderer observation, but push is not in
1319
+ Core's cooperatively cancellable method set; the host/provider mutation can
1320
+ continue. Aborting is not rollback, and no `ArcaneOperation` receipt is added
1321
+ to the provider-native result.
1322
+
1323
+ ### Example
1324
+
1325
+ The helper is deliberately not invoked. Call it only after an admitted UI has
1326
+ obtained explicit publishing confirmation.
1327
+
1328
+ ```javascript
1329
+ async function pushVerifiedModelAfterConfirmation(model) {
1330
+ function reportPushChunk(chunk) {
1331
+ console.info(chunk.status ?? 'Push is running.');
1332
+ }
1333
+
1334
+ return globalThis.Arcane.ollama.push(model, {insecure: false}, {
1335
+ onChunk: reportPushChunk,
1336
+ timeoutMs: 3000000
1337
+ });
1338
+ }
1339
+ ```
1340
+
1341
+ ## Arcane.ollama.create()
1342
+
1343
+ ### Overview
1344
+
1345
+ `Arcane.ollama.create(request, streamOptions?)` exposes a tightly restricted
1346
+ verified model-definition create path. Core accepts creation only for an exact
1347
+ app-owned model and rechecks the base model and resource admission. Prefer the
1348
+ managed selection or `createBrain()` workflow unless the application package
1349
+ explicitly owns this definition.
1350
+
1351
+ ### Parameters
1352
+
1353
+ The closed request is at most 8 MiB and requires a valid `model`. The direct
1354
+ parser recognizes `from`, `files`, `adapters`, `template`, `license`, `system`,
1355
+ `parameters`, `messages`, and `quantize`. The managed verified boundary requires
1356
+ `from`, normalized `system`, and `parameters` to match the package definition
1357
+ exactly and forbids `files` and `adapters`. Do not add other provider-native
1358
+ controls unless the package contract expressly owns them. Reserved Arcane and
1359
+ rollback aliases are denied. Stream controls are a callback or `{onChunk,
1360
+ signal, timeoutMs}`.
1361
+
1362
+ ### Return value
1363
+
1364
+ It resolves to Ollama's bounded provider-native create envelope. With
1365
+ `onChunk`, callbacks receive `(chunk, {operation: "create", streamId})`, and
1366
+ the promise resolves to the final chunk. This raw response does not include an
1367
+ `ArcaneOperation`.
1368
+
1369
+ ### Availability
1370
+
1371
+ This is an exclusive desktop Core mutation requiring `ai.models.manage`,
1372
+ verified-only package policy, and an exact app-owned definition. Unverified
1373
+ mode, Android, browser previews, and reserved aliases cannot use it.
1374
+
1375
+ ### Errors and recovery
1376
+
1377
+ `MODEL_NOT_APP_VERIFIED`, `MODEL_DEFINITION_VERIFICATION_FAILED`, managed-
1378
+ workflow, resource-admission, and unverified-mutation errors require the
1379
+ package-owned workflow rather than edited renderer input. Provider failure can
1380
+ leave uncertain local creation state; refresh model inventory and verification
1381
+ before retrying.
1382
+
1383
+ ### Streaming, cancellation, and events
1384
+
1385
+ Create chunks are filtered by the wrapper's stream ID. The default renderer
1386
+ timeout is 50 minutes. A supplied signal rejects renderer observation, but
1387
+ Core does not cooperatively cancel this raw create mutation; verify final local
1388
+ state after timeout or teardown.
1389
+
1390
+ ### Example
1391
+
1392
+ The helper is intentionally not invoked. Its definition must come from
1393
+ immutable package-owned policy, never user-edited JSON.
1394
+
1395
+ ```javascript
1396
+ async function createVerifiedDefinition(definition) {
1397
+ function reportCreateChunk(chunk) {
1398
+ console.info(chunk.status ?? 'Create is running.');
1399
+ }
1400
+
1401
+ return globalThis.Arcane.ollama.create({
1402
+ model: definition.name,
1403
+ from: definition.from,
1404
+ system: definition.system,
1405
+ parameters: definition.parameters
1406
+ }, {
1407
+ onChunk: reportCreateChunk,
1408
+ timeoutMs: 3000000
1409
+ });
1410
+ }
1411
+ ```
1412
+
1413
+ ## Arcane.ollama.copy()
1414
+
1415
+ ### Overview
1416
+
1417
+ `Arcane.ollama.copy(source, destination)` is intentionally denied to every
1418
+ application. Raw alias copying is reserved to Arcane's integrity-gated managed
1419
+ selection workflow.
1420
+
1421
+ ### Parameters
1422
+
1423
+ `source` and `destination` are required valid Ollama model names. Valid names do
1424
+ not make the operation admissible.
1425
+
1426
+ ### Return value
1427
+
1428
+ The application contract is `Promise<never>`: Core always rejects before a
1429
+ provider copy and produces no success result.
1430
+
1431
+ ### Availability
1432
+
1433
+ The method sits behind the desktop Core `ai.models.manage` boundary but remains
1434
+ denied under both verified and unverified application policy. Android and
1435
+ browser previews do not expose it.
1436
+
1437
+ ### Errors and recovery
1438
+
1439
+ Core returns `UNVERIFIED_MODEL_MUTATION_FORBIDDEN` with a resolution directing
1440
+ the caller to a managed model-selection workflow. Treat it as a policy result,
1441
+ not a transient provider failure.
1442
+
1443
+ ### Streaming, cancellation, and events
1444
+
1445
+ The method does not reach the provider, stream chunks, accept a signal, or emit
1446
+ operation events.
1447
+
1448
+ ### Example
1449
+
1450
+ ```javascript
1451
+ try {
1452
+ await globalThis.Arcane.ollama.copy(
1453
+ 'gemma3:latest',
1454
+ 'my-copy:latest'
1455
+ );
1456
+ throw new Error('Raw Ollama copy unexpectedly succeeded.');
1457
+ } catch (error) {
1458
+ if (error.code !== 'UNVERIFIED_MODEL_MUTATION_FORBIDDEN') {
1459
+ throw error;
1460
+ }
1461
+ console.info('Use the managed Arcane selection workflow.');
1462
+ }
1463
+ ```
1464
+
1465
+ ## Arcane.ollama.delete()
1466
+
1467
+ ### Overview
1468
+
1469
+ `Arcane.ollama.delete(model)` deletes an exact package-owned verified model
1470
+ through Ollama. This destructive raw mutation can invalidate application state;
1471
+ prefer the owning managed lifecycle and require explicit user authorization.
1472
+
1473
+ ### Parameters
1474
+
1475
+ `model` is a required Ollama name and must resolve to an exact app-owned
1476
+ verified definition. Reserved Arcane and rollback aliases are denied.
1477
+
1478
+ ### Return value
1479
+
1480
+ It resolves to Ollama's bounded provider-native delete response. The raw result
1481
+ does not contain a managed `ArcaneOperation` receipt.
1482
+
1483
+ ### Availability
1484
+
1485
+ This is an exclusive desktop Core mutation requiring `ai.models.manage` and
1486
+ verified-only package policy. Unverified mode is inference-only. Android and
1487
+ browser previews do not expose delete.
1488
+
1489
+ ### Errors and recovery
1490
+
1491
+ Invalid model, unverified-policy, missing app definition, and reserved-alias
1492
+ errors require the managed package workflow. Provider failure can leave the
1493
+ model's final state uncertain; refresh raw inventory and package verification
1494
+ before deciding whether a retry is safe.
1495
+
1496
+ ### Streaming, cancellation, and events
1497
+
1498
+ Delete is non-streaming, emits no managed operation events, and exposes no
1499
+ signal. The renderer timeout is two minutes. Page teardown can stop observation
1500
+ without rolling back host work.
1501
+
1502
+ ### Example
1503
+
1504
+ The helper is not invoked. Call it only after the owning application has shown
1505
+ the exact verified model and obtained destructive-action confirmation.
1506
+
1507
+ ```javascript
1508
+ async function deleteVerifiedModelAfterConfirmation(model) {
1509
+ return globalThis.Arcane.ollama.delete(model);
1510
+ }
1511
+ ```
1512
+
1513
+ ## Arcane.ollama.selection()
1514
+
1515
+ ### Overview
1516
+
1517
+ `Arcane.ollama.selection()` reads the current managed Arcane model preference
1518
+ and resolved runtime/provider state. Use it in Settings or Shell to explain the
1519
+ managed selection; use `localAI.status()` for an application's currently
1520
+ runnable model catalog.
1521
+
1522
+ ### Parameters
1523
+
1524
+ The method takes no arguments.
1525
+
1526
+ ### Return value
1527
+
1528
+ It resolves to `ArcaneModelSelection`: preference, recommended/effective/active
1529
+ variant, model and alias, default/boot settings, provider and OpenAI model,
1530
+ response length, credential-presence Boolean, bounded GPU diagnostics, and
1531
+ `recommendationPending`. The snapshot is diagnostic state, not admission for a
1532
+ later request.
1533
+
1534
+ ### Availability
1535
+
1536
+ This desktop Core read requires `ai.models.read` and is admitted only to
1537
+ Settings and Shell. It is not projected to Android or browser previews.
1538
+
1539
+ ### Errors and recovery
1540
+
1541
+ Method admission and transport errors require the correct app or host. If
1542
+ automatic recommendation is pending, display that state rather than treating
1543
+ the current model as a failed selection; refresh after the managed workflow
1544
+ completes.
1545
+
1546
+ ### Streaming, cancellation, and events
1547
+
1548
+ This is a non-streaming snapshot with no method event or signal. A concurrent
1549
+ selection or settings mutation can make it stale immediately.
1550
+
1551
+ ### Example
1552
+
1553
+ ```javascript
1554
+ const selection = await globalThis.Arcane.ollama.selection();
1555
+
1556
+ console.info({
1557
+ preference: selection.preference,
1558
+ effectiveVariant: selection.effectiveVariant,
1559
+ model: selection.model,
1560
+ pending: selection.recommendationPending
1561
+ });
1562
+ ```
1563
+
1564
+ ## Arcane.ollama.select()
1565
+
1566
+ ### Overview
1567
+
1568
+ `Arcane.ollama.select(preference)` runs the managed model-selection workflow.
1569
+ It can download a verified base, create or replace a managed alias, perform
1570
+ native resource admission, and change persisted model state. Use it only from
1571
+ an admitted Settings or Shell choice with explicit user intent.
1572
+
1573
+ ### Parameters
1574
+
1575
+ `preference` is one of `"auto"`, `"3b"`, `"8b"`, `"12b"`, `"20b"`, or
1576
+ `"120b"`. It is a managed size preference, not an arbitrary Ollama model name.
1577
+ The wrapper maps an omitted or empty value to `"auto"`.
1578
+
1579
+ ### Return value
1580
+
1581
+ It resolves to the selected model, alias, variant, preference, recommendation,
1582
+ base model, creation and alias-change effects, model-store and GPU evidence,
1583
+ final compatibility, automatic-candidate degradation/failures when relevant,
1584
+ rollback-snapshot state, and a completed `ArcaneOperation`.
1585
+
1586
+ ### Availability
1587
+
1588
+ This is an exclusive desktop Core mutation requiring `ai.models.manage` and
1589
+ Settings or Shell identity. Package-bound verified definitions and current
1590
+ native capacity govern which preference can complete. Android does not expose
1591
+ the workflow.
1592
+
1593
+ ### Errors and recovery
1594
+
1595
+ `INVALID_ARCANE_MODEL_PREFERENCE` requires an enum value. Registry, integrity,
1596
+ definition, native-admission, storage, alias, load, and rollback errors preserve
1597
+ stable codes and resolutions. If `rollbackSnapshotRetained` is true on success,
1598
+ surface the recovery detail rather than deleting the retained alias from
1599
+ renderer code.
1600
+
1601
+ ### Streaming, cancellation, and events
1602
+
1603
+ Selection emits standard operation lifecycle, log, and progress events. The
1604
+ wrapper uses a 50-minute timeout and exposes no signal; Core does not
1605
+ cooperatively cancel this managed workflow. A renderer timeout is not evidence
1606
+ that download or alias mutation stopped, so refresh `selection()` and status
1607
+ before retrying.
1608
+
1609
+ ### Example
1610
+
1611
+ The helper is deliberately not invoked; call it only after the user confirms
1612
+ the managed size choice and possible download.
1613
+
1614
+ ```javascript
1615
+ async function selectManagedModelAfterConfirmation(preference) {
1616
+ const allowed = new Set(['auto', '3b', '8b', '12b', '20b', '120b']);
1617
+ if (!allowed.has(preference)) {
1618
+ throw new TypeError('Choose a documented Arcane model preference.');
1619
+ }
1620
+ return globalThis.Arcane.ollama.select(preference);
1621
+ }
1622
+ ```
1623
+
1624
+ ## Arcane.ollama.settings()
1625
+
1626
+ ### Overview
1627
+
1628
+ `Arcane.ollama.settings()` reads the complete managed AI runtime/provider
1629
+ settings snapshot for the Settings application. It returns the same
1630
+ `ArcaneModelSelection` shape as `selection()`, but has the stronger
1631
+ settings-management boundary.
1632
+
1633
+ ### Parameters
1634
+
1635
+ The method takes no arguments.
1636
+
1637
+ ### Return value
1638
+
1639
+ The snapshot contains model preference and aliases, default/boot settings,
1640
+ provider, OpenAI model, response length, protected-credential presence, GPU
1641
+ diagnostics, and recommendation state. Credentials are never returned.
1642
+
1643
+ ### Availability
1644
+
1645
+ This is a desktop Core Settings-only API requiring `ai.settings.manage`.
1646
+ Android and browser previews do not expose it.
1647
+
1648
+ ### Errors and recovery
1649
+
1650
+ Method-admission or transport errors require the correct Settings host. Treat
1651
+ the result as a single snapshot; do not merge stale provider fields into a
1652
+ later runtime-settings save.
1653
+
1654
+ ### Streaming, cancellation, and events
1655
+
1656
+ This is a non-streaming read with no method event or signal. A concurrent
1657
+ settings or selection mutation can invalidate it immediately.
1658
+
1659
+ ### Example
1660
+
1661
+ ```javascript
1662
+ const settings = await globalThis.Arcane.ollama.settings();
1663
+
1664
+ console.info({
1665
+ defaultModel: settings.defaultModel,
1666
+ bootLoad: settings.bootLoad,
1667
+ contextLength: settings.contextLength
1668
+ });
1669
+ ```
1670
+
1671
+ ## Arcane.ollama.saveSettings()
1672
+
1673
+ ### Overview
1674
+
1675
+ `Arcane.ollama.saveSettings(settings)` saves runtime-owned Ollama defaults. Use
1676
+ it for default model, managed startup load, residency, and context. Use
1677
+ `select()` for the size preference and `ai.saveProviderSettings()` for provider,
1678
+ OpenAI model, credential, and response length.
1679
+
1680
+ ### Parameters
1681
+
1682
+ Recognized fields are `defaultModel`, `bootLoad`, `bootKeepAlive`, and
1683
+ `contextLength`; omissions preserve current values. `defaultModel` uses the
1684
+ Ollama name pattern. `bootLoad` is Boolean. `bootKeepAlive` is `"5m"`, `"30m"`,
1685
+ `"1h"`, `"24h"`, or `"-1"`. `contextLength` is `0` for Automatic or
1686
+ 1,024-262,144. Unknown keys, including stale provider/preference fields, are
1687
+ ignored so they cannot overwrite newer provider selection; do not send them.
1688
+
1689
+ ### Return value
1690
+
1691
+ It resolves to the complete updated `ArcaneModelSelection` settings snapshot
1692
+ plus a completed `operation`. It does not return selection-only mutation fields
1693
+ such as `created`, `baseModel`, or `aliasChanged`.
1694
+
1695
+ ### Availability
1696
+
1697
+ This is an exclusive desktop Core Settings mutation requiring
1698
+ `ai.settings.manage`. When Ollama is selected, the default model must be
1699
+ installed. Enabling boot load performs resource admission and loads the model.
1700
+ Android does not expose this method.
1701
+
1702
+ ### Errors and recovery
1703
+
1704
+ Correct invalid model, keep-alive, or context values locally. A missing default
1705
+ model, native-admission failure, load failure, or persistence error requires the
1706
+ stable resolution and a fresh settings read before retry. Unknown stale fields
1707
+ are intentionally ignored rather than validated.
1708
+
1709
+ ### Streaming, cancellation, and events
1710
+
1711
+ The save emits standard operation events but no provider chunks. It uses the
1712
+ 50-minute renderer timeout and has no signal. Core does not cooperatively cancel
1713
+ the mutation, so refresh `settings()` after an uncertain completion.
1714
+
1715
+ ### Example
1716
+
1717
+ The helper fetches current state and changes only runtime-owned fields. It is
1718
+ not invoked until an admitted Settings UI has confirmed the desired values.
1719
+
1720
+ ```javascript
1721
+ async function saveRuntimeSettingsAfterConfirmation(desired) {
1722
+ return globalThis.Arcane.ollama.saveSettings({
1723
+ defaultModel: desired.defaultModel,
1724
+ bootLoad: desired.bootLoad,
1725
+ bootKeepAlive: desired.bootKeepAlive,
1726
+ contextLength: desired.contextLength
1727
+ });
1728
+ }
1729
+ ```
1730
+
1731
+ ## Arcane.ollama.createBrain()
1732
+
1733
+ ### Overview
1734
+
1735
+ `Arcane.ollama.createBrain(definition)` creates a managed
1736
+ `arcane-<slug>:latest` model from an approved base. It can pull or repair the
1737
+ base, create the alias, verify it, and optionally make it the default. Use it
1738
+ only from Settings after explaining download, storage, and default-model
1739
+ effects.
1740
+
1741
+ ### Parameters
1742
+
1743
+ `baseModel` is required and uses the Ollama name pattern. `name` defaults to
1744
+ `"my-brain"` and is normalized to a lowercase 1-64 character slug using
1745
+ letters, digits, dots, underscores, and hyphens. `contextLength` defaults to `0`
1746
+ for inherited/automatic; send only `0` or an explicit 1,024-262,144 value.
1747
+ `makeDefault` defaults to false. Unknown keys are ignored and should not be
1748
+ sent.
1749
+
1750
+ ### Return value
1751
+
1752
+ It resolves to `{model, baseModel, defaultModel, operation}`. `model` is the
1753
+ created Arcane alias, `defaultModel` reports whether it became the default, and
1754
+ `operation` is the completed managed receipt.
1755
+
1756
+ ### Availability
1757
+
1758
+ This is an exclusive desktop Core Settings mutation requiring
1759
+ `ai.models.manage`. The package-owned verified workflow, registry evidence,
1760
+ resource admission, and reserved-alias rules remain authoritative. Android
1761
+ does not expose it.
1762
+
1763
+ ### Errors and recovery
1764
+
1765
+ Invalid base/name/context, model-policy, registry, integrity, storage,
1766
+ admission, provider-create, alias-verification, and persistence failures require
1767
+ the stable resolution. After uncertain completion, refresh inventory and
1768
+ settings before retrying; do not manually copy or delete managed aliases.
1769
+
1770
+ ### Streaming, cancellation, and events
1771
+
1772
+ The workflow emits standard operation events but does not expose raw Ollama
1773
+ chunks. It has a 50-minute renderer timeout and no signal; Core does not
1774
+ cooperatively cancel it, so teardown is not rollback.
1775
+
1776
+ ### Example
1777
+
1778
+ This helper is not invoked until the Settings application confirms the exact
1779
+ base, name, context, and default-model effect.
1780
+
1781
+ ```javascript
1782
+ async function createBrainAfterConfirmation(baseModel, name) {
1783
+ return globalThis.Arcane.ollama.createBrain({
1784
+ baseModel: baseModel,
1785
+ name: name,
1786
+ contextLength: 0,
1787
+ makeDefault: false
1788
+ });
1789
+ }
1790
+ ```
1791
+
1792
+ ## Arcane.ollama.serviceSettings()
1793
+
1794
+ ### Overview
1795
+
1796
+ `Arcane.ollama.serviceSettings()` reads host-owned Ollama service configuration.
1797
+ Use it to initialize the advanced Settings surface. Its object is intentionally
1798
+ platform-dependent; feature-detect support and fields instead of assuming one
1799
+ cross-platform exact shape.
1800
+
1801
+ ### Parameters
1802
+
1803
+ The method takes no arguments.
1804
+
1805
+ ### Return value
1806
+
1807
+ Microsoft NT reports effective settings and support state, including context,
1808
+ residency, loaded-model, parallelism, queue, flash-attention, K/V-cache, and
1809
+ no-cloud controls. Linux currently returns `supported: false` with a reason and
1810
+ bounded administrative defaults because systemd override management remains
1811
+ administrator-owned.
1812
+
1813
+ ### Availability
1814
+
1815
+ This is a desktop Core Settings-only method requiring `ai.settings.manage`.
1816
+ The current Android projection and browser previews do not expose host service
1817
+ settings.
1818
+
1819
+ ### Errors and recovery
1820
+
1821
+ Transport or native-adapter errors should leave controls read-only and present
1822
+ the returned resolution. `supported: false` is a valid platform state, not a
1823
+ reason to attempt renderer-side service-file edits.
1824
+
1825
+ ### Streaming, cancellation, and events
1826
+
1827
+ This is a non-streaming read with no method event or signal. Treat the result
1828
+ as a snapshot; machine capacity or administrator configuration can change
1829
+ before a later save.
1830
+
1831
+ ### Example
1832
+
1833
+ ```javascript
1834
+ const state = await globalThis.Arcane.ollama.serviceSettings();
1835
+
1836
+ if (state.supported === false) {
1837
+ console.info(state.reason ?? 'Service settings are managed externally.');
1838
+ } else {
1839
+ console.info(state.numParallel, state.maxLoadedModels);
1840
+ }
1841
+ ```
1842
+
1843
+ ## Arcane.ollama.saveServiceSettings()
1844
+
1845
+ ### Overview
1846
+
1847
+ `Arcane.ollama.saveServiceSettings(settings)` applies host-level Ollama service
1848
+ settings. It can restart the managed service, unload models, clamp requested
1849
+ parallel/load values to current capacity, and affect every local client. Use it
1850
+ only in advanced Settings with explicit machine-wide impact disclosure.
1851
+
1852
+ ### Parameters
1853
+
1854
+ Omitted fields receive defaults rather than preserving current values, so send
1855
+ the complete desired object. `contextLength` is 0-262,144; `keepAlive` is
1856
+ `"-1"`, `"0"`, or 1-9,999 plus `m` or `h`; `maxLoadedModels` is 0-16;
1857
+ `numParallel` is 1-16; `maxQueue` is 1-4,096; `flashAttention` and `noCloud` are
1858
+ Booleans; and `kvCacheType` is `"f16"`, `"q8_0"`, or `"q4_0"`. Defaults are
1859
+ 0, `"5m"`, 1, 1, 512, false, `"f16"`, and true respectively. Unknown keys are
1860
+ ignored and should not be sent.
1861
+
1862
+ ### Return value
1863
+
1864
+ It resolves to the native platform result plus a completed `ArcaneOperation`.
1865
+ Microsoft NT reports requested and effective values, support/clamping detail,
1866
+ restart state, recommendation, and post-change health. Require
1867
+ `healthy === true` when that field is present.
1868
+
1869
+ ### Availability
1870
+
1871
+ This is a privileged, exclusive desktop Core Settings method requiring
1872
+ `ai.settings.manage`. Microsoft NT currently applies the managed change. Linux
1873
+ rejects with `OLLAMA_SERVICE_SETTINGS_MANUAL` because the systemd override is
1874
+ administrator-managed. Android does not expose it.
1875
+
1876
+ ### Errors and recovery
1877
+
1878
+ Correct invalid ranges and enums before calling. Unsupported/manual-platform,
1879
+ managed-service health, installation-lease, apply, restart, postcondition, and
1880
+ rollback errors require the stable resolution. After an uncertain completion,
1881
+ read `serviceSettings()` and local status before another mutation. Never edit
1882
+ service files or environment from renderer code.
1883
+
1884
+ ### Streaming, cancellation, and events
1885
+
1886
+ The workflow emits standard operation lifecycle and progress events, not raw
1887
+ provider chunks. It uses a 50-minute renderer timeout and has no signal. Core
1888
+ does not cooperatively cancel it; timeout or page teardown can occur while the
1889
+ machine-wide transaction continues.
1890
+
1891
+ ### Example
1892
+
1893
+ The helper sends a complete desired state and is deliberately not invoked until
1894
+ the Settings application has obtained explicit restart confirmation.
1895
+
1896
+ ```javascript
1897
+ async function saveServiceSettingsAfterConfirmation(desired) {
1898
+ return globalThis.Arcane.ollama.saveServiceSettings({
1899
+ contextLength: desired.contextLength,
1900
+ keepAlive: desired.keepAlive,
1901
+ maxLoadedModels: desired.maxLoadedModels,
1902
+ numParallel: desired.numParallel,
1903
+ maxQueue: desired.maxQueue,
1904
+ flashAttention: desired.flashAttention,
1905
+ kvCacheType: desired.kvCacheType,
1906
+ noCloud: desired.noCloud
1907
+ });
1908
+ }
1909
+ ```