arcane-os 0.41.0 → 0.42.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.42.0
4
+
5
+ - Accept the optional boolean `responseToUsersPromptComplete` in conversation
6
+ closing-report arguments, preserving both `true` and `false` and leaving the
7
+ normalized record unchanged when the field is omitted.
8
+ - Add `createConversationClosingReportTool({responseToUsersPromptComplete:
9
+ {required:true,description}})` so applications can require the completion
10
+ flag and supply its complete description. Omitting the option preserves the
11
+ existing schema; an optional declaration defaults `required` to `false`.
12
+ Applications continue to own tool execution,
13
+ continuation, terminal closeout and storage; the SDK adds no runner or
14
+ automatic follow-up behavior and performs no saved-history migration.
15
+
3
16
  ## 0.41.0
4
17
 
5
18
  - Add `createTwinCloudTTSProvider` through `arcane-os/ai/browser-speech`,
package/README.md CHANGED
@@ -19,7 +19,7 @@ version-locked SDK runtime, while an integrated Arcane checkout uses its live
19
19
  `arcane/` runtime. Both profiles share the theme, packaging, event, cancellation,
20
20
  and browser run contracts while retaining their selected application layout.
21
21
 
22
- This checkout defines the `0.41.0` SDK contract. Applications pin one exact npm
22
+ This checkout defines the `0.42.0` SDK contract. Applications pin one exact npm
23
23
  version and lockfile; registry state is deliberately not baked into application
24
24
  artifacts.
25
25
 
@@ -489,8 +489,8 @@
489
489
  "summary": "Defines the closing-report tool, instruction, result normalizer, call classifier, and formatter.",
490
490
  "availability": "Cross-host",
491
491
  "protocol": "In-process only",
492
- "normalization": "Required user-facing message remains distinct from the complete final_message; normalized results expose message, finalMessage, and rememberedActions.",
493
- "surface": "Seven constants/helpers for closing reports; the sole-call schema requires message and final_message. formatConversationClosingReportText(value) exposes the existing &, <, and > escaping for any string, including whitespace-only chunks, and the complete report formatter reuses it."
492
+ "normalization": "Required user-facing message remains distinct from the complete final_message; normalized results expose message, finalMessage, and rememberedActions. Optional responseToUsersPromptComplete is preserved only when supplied as a boolean, with no coercion or default; it is transient app-owned control metadata outside saved history.",
493
+ "surface": "Seven constants/helpers for closing reports; the sole-call schema requires message and final_message. createConversationClosingReportTool optionally accepts responseToUsersPromptComplete:{required:false,description:<nonblank app-owned string>} to declare the boolean, or required:true to require it; omission preserves the existing schema. The normalizer remains independent of factory options and orchestration remains app-owned. formatConversationClosingReportText(value) exposes the existing &, <, and > escaping for any string, including whitespace-only chunks, and the complete report formatter reuses it."
494
494
  },
495
495
  {
496
496
  "file": "runtime/arcane/modules/ConversationTimebox.js",
@@ -1933,6 +1933,35 @@ replaces `&`, `<`, and `>` with `&amp;`, `&lt;`, and `&gt;` respectively. It
1933
1933
  preserves all other text and does not trim, validate a report, render, or persist
1934
1934
  anything. Use the same operation for live text chunks and complete final text.
1935
1935
 
1936
+ An application may opt into completion metadata when creating the tool:
1937
+
1938
+ ```javascript
1939
+ import {createConversationClosingReportTool} from 'arcane-os/conversation-closing-report';
1940
+
1941
+ const tool=createConversationClosingReportTool({
1942
+ responseToUsersPromptComplete:{
1943
+ required:true,
1944
+ description:"Use true only when this response's messages and successful tool actions complete the whole current user request. Use false if any answer or action still needs a model response, whether or not this tool returns data."
1945
+ }
1946
+ });
1947
+ ```
1948
+
1949
+ The option declares a boolean `responseToUsersPromptComplete` argument. Its
1950
+ `description` must be a nonblank string and is preserved completely;
1951
+ `required` defaults to `false`. Omitting the option preserves the existing
1952
+ schema, including its required fields. This changes only the declaration, not
1953
+ the closeout instruction or sole-call classifier.
1954
+
1955
+ `normalizeConversationClosingReport()` accepts that optional boolean in an
1956
+ object or JSON string and preserves `true` or `false` in the returned record
1957
+ under the same key. Omission leaves the key absent; other supplied types raise
1958
+ `CONVERSATION_CLOSING_REPORT_INVALID` without coercion. The normalizer does not
1959
+ consume factory options or enforce an application's required setting. The
1960
+ application owns completion decisions, sibling-call handling, and continuation.
1961
+ The flag is transient control metadata, not conversation content or a saved
1962
+ history field. These helpers perform no persistence or orchestration, and the
1963
+ formatter still returns only the formatted `finalMessage`.
1964
+
1936
1965
  Exact exports: `CONVERSATION_CLOSING_REPORT_TOOL_NAME`, `classifyConversationClosingReportCalls`, `conversationClosingReportInstruction`, `createConversationClosingReportTool`, `formatConversationClosingReport`, `formatConversationClosingReportText`, `normalizeConversationClosingReport`.
1937
1966
 
1938
1967
  ### Availability and normalization
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arcane-os",
3
- "version": "0.41.0",
3
+ "version": "0.42.0",
4
4
  "description": "Arcane OS JavaScript SDK, project-local CLI, browser runtime, and repository-portable application packager.",
5
5
  "type": "module",
6
6
  "main": "./src/index.mjs",
@@ -85,7 +85,7 @@
85
85
  "scripts": {
86
86
  "test": "npm run test:unit && npm run test:functional && npm run test:integration && npm run test:regression",
87
87
  "test:release": "node ./bin/arcane-test.mjs test/npm-release.test.mjs",
88
- "test:unit": "node ./bin/arcane-test.mjs test/app-descriptor.test.mjs test/app-schema.test.mjs test/app-selection.test.mjs test/contracts.test.mjs test/doctor.test.mjs test/mail-credentials.test.mjs test/mail-outbox.test.mjs test/mail-public-api.test.mjs test/mail-send.test.mjs test/mail-transport.test.mjs test/targets.test.mjs test/workspace-operation-lock.test.mjs",
88
+ "test:unit": "node ./bin/arcane-test.mjs test/app-descriptor.test.mjs test/app-schema.test.mjs test/app-selection.test.mjs test/contracts.test.mjs test/conversation-closing-report.test.mjs test/doctor.test.mjs test/mail-credentials.test.mjs test/mail-outbox.test.mjs test/mail-public-api.test.mjs test/mail-send.test.mjs test/mail-transport.test.mjs test/targets.test.mjs test/workspace-operation-lock.test.mjs",
89
89
  "test:functional": "node ./bin/arcane-test.mjs test/ai-request-model.test.mjs test/ai-request-retry.test.mjs test/ai-stream-cancellation.test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-stream-speech.test.mjs test/chat-transcript-scroll.test.mjs test/chat-transient-retention.test.mjs test/cli.test.mjs test/continuous-voice-capture.test.mjs test/dbopfs-document-library.test.mjs test/dbopfs-png.test.mjs test/dbopfs.test.mjs test/dev-server.test.mjs test/dev-pwa.test.mjs test/dom-event-instrumentation.test.mjs test/event-manager.test.mjs test/events.test.mjs test/file-preview.test.mjs test/import-map.test.mjs test/mail-cli.test.mjs test/mail-runtime.test.mjs test/mail-server.test.mjs test/markdown-editor.test.mjs test/markdown-source-map.test.mjs test/modal.test.mjs test/packaging.test.mjs test/pwa-packaging.test.mjs test/pwa-client.test.mjs test/pwa-install.test.mjs test/pwa-worker.test.mjs test/persistent-ai-chat-session.test.mjs test/reference-completeness.test.mjs test/runtime-api-behavior.test.mjs test/runtime.test.mjs test/scaffold.test.mjs test/speech-playback.test.mjs test/site.test.mjs test/twin-cloud.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
90
90
  "test:integration": "node ./bin/arcane-test.mjs test/installed-package-runtime.test.mjs test/root-app-layout.test.mjs test/integrated-shared.test.mjs test/integrated-workspace.test.mjs test/mail-browser.test.mjs test/native-plan.test.mjs test/native-provider-loader.test.mjs test/npm-release.test.mjs test/release-bundle.test.mjs test/release-capability-smoke.test.mjs test/shared-payload-batch.test.mjs test/tarball.test.mjs test/browser-wasm-cpu.test.mjs test/wllama-webgpu-runtime.test.mjs",
91
91
  "test:regression": "node ./bin/arcane-test.mjs test/channel-workflows.test.mjs test/html-import-registration.test.mjs test/logging-regression.test.mjs test/markdown-speech.test.mjs test/prepared-speech.test.mjs test/native-provider-generation.test.mjs test/speech-queue-regression.test.mjs test/testing.test.mjs test/test-sets.test.mjs",
@@ -11,7 +11,8 @@ const TOOL_NAME_PATTERN=/^[a-z][a-z0-9_]*$/;
11
11
  const REPORT_FIELDS=new Set([
12
12
  'message',
13
13
  'final_message',
14
- 'remembered_actions'
14
+ 'remembered_actions',
15
+ 'responseToUsersPromptComplete'
15
16
  ]);
16
17
 
17
18
  function invalid(message){
@@ -88,11 +89,14 @@ function completeValue(value){
88
89
  /**
89
90
  * Creates a provider-neutral terminal tool for one user-facing conversation
90
91
  * closeout. The tool performs no inference, persistence, rendering, task
91
- * execution, navigation, or external delivery.
92
+ * execution, navigation, or external delivery. An optional
93
+ * responseToUsersPromptComplete declaration adds app-owned completion metadata;
94
+ * its description is required and its required setting defaults to false.
92
95
  */
93
96
  export function createConversationClosingReportTool({
94
97
  name=DEFAULT_TOOL_NAME,
95
- description='Prepare a complete closing report when the user clearly ends a conversation.'
98
+ description='Prepare a complete closing report when the user clearly ends a conversation.',
99
+ responseToUsersPromptComplete
96
100
  }={}){
97
101
  if(!is.string(name)||!TOOL_NAME_PATTERN.test(name)){
98
102
  throw invalid('The closing-report tool name is invalid.');
@@ -101,7 +105,7 @@ export function createConversationClosingReportTool({
101
105
  throw invalid('The closing-report tool description is invalid.');
102
106
  }
103
107
 
104
- return completeValue({
108
+ const tool={
105
109
  type:'function',
106
110
  function:{
107
111
  name,
@@ -145,7 +149,33 @@ export function createConversationClosingReportTool({
145
149
  required:['message','final_message']
146
150
  }
147
151
  }
148
- });
152
+ };
153
+
154
+ if(responseToUsersPromptComplete!==undefined){
155
+ if(!isPlainRecord(responseToUsersPromptComplete)){
156
+ throw invalid('responseToUsersPromptComplete options must be an object.');
157
+ }
158
+ const {
159
+ required=false,
160
+ description:completionDescription
161
+ }=responseToUsersPromptComplete;
162
+ if(!is.boolean(required)){
163
+ throw invalid('responseToUsersPromptComplete.required must be a boolean.');
164
+ }
165
+ tool.function.parameters.properties.responseToUsersPromptComplete={
166
+ type:'boolean',
167
+ description:normalizedText(
168
+ completionDescription,
169
+ 'responseToUsersPromptComplete.description',
170
+ {required:true}
171
+ )
172
+ };
173
+ if(required){
174
+ tool.function.parameters.required.push('responseToUsersPromptComplete');
175
+ }
176
+ }
177
+
178
+ return completeValue(tool);
149
179
  }
150
180
 
151
181
  /**
@@ -181,13 +211,22 @@ export function normalizeConversationClosingReport(value){
181
211
  throw invalid(`Unexpected closing-report field: ${unexpectedField}.`);
182
212
  }
183
213
 
184
- return completeValue({
214
+ const report={
185
215
  message:normalizedText(source.message,'message',{required:true}),
186
216
  finalMessage:normalizedFinalMessage(source.final_message),
187
217
  rememberedActions:normalizeRememberedConversationActions(
188
218
  source.remembered_actions||[]
189
219
  )
190
- });
220
+ };
221
+
222
+ if(Object.hasOwn(source,'responseToUsersPromptComplete')){
223
+ if(!is.boolean(source.responseToUsersPromptComplete)){
224
+ throw invalid('responseToUsersPromptComplete must be a boolean.');
225
+ }
226
+ report.responseToUsersPromptComplete=source.responseToUsersPromptComplete;
227
+ }
228
+
229
+ return completeValue(report);
191
230
  }
192
231
 
193
232
  /**
@@ -233,13 +272,17 @@ export function classifyConversationClosingReportCalls(calls={}, {
233
272
  }
234
273
 
235
274
  export function formatConversationClosingReport(value){
236
- const normalizedInput=isPlainRecord(value)&&value.finalMessage!==undefined
237
- ?{
275
+ let normalizedInput=value;
276
+ if(isPlainRecord(value)&&value.finalMessage!==undefined){
277
+ normalizedInput={
238
278
  message:value.message,
239
279
  final_message:value.finalMessage,
240
280
  remembered_actions:value.rememberedActions,
281
+ };
282
+ if(Object.hasOwn(value,'responseToUsersPromptComplete')){
283
+ normalizedInput.responseToUsersPromptComplete=value.responseToUsersPromptComplete;
241
284
  }
242
- :value;
285
+ }
243
286
  return formatConversationClosingReportText(
244
287
  normalizeConversationClosingReport(normalizedInput).finalMessage
245
288
  );