@case-framework/survey-assistant 0.2.3 → 0.4.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.
Files changed (87) hide show
  1. package/README.md +12 -4
  2. package/dist/{authoring-references-ChDTVnms.mjs → authoring-references-yyYC4Ydi.mjs} +2 -2
  3. package/dist/{authoring-references-ChDTVnms.mjs.map → authoring-references-yyYC4Ydi.mjs.map} +1 -1
  4. package/dist/capabilities-default.d.mts +1 -1
  5. package/dist/capabilities-default.mjs +1 -1
  6. package/dist/{constants-BK1-g6pR.d.mts → constants-k1b_evIb.d.mts} +7 -4
  7. package/dist/constants-k1b_evIb.d.mts.map +1 -0
  8. package/dist/{controller-proxy-DY36XFV3.mjs → controller-proxy-jWIPOZAv.mjs} +18 -8
  9. package/dist/controller-proxy-jWIPOZAv.mjs.map +1 -0
  10. package/dist/{controller-proxy-CIDRd8Wu.d.mts → controller-proxy-quQjtA7j.d.mts} +5 -2
  11. package/dist/controller-proxy-quQjtA7j.d.mts.map +1 -0
  12. package/dist/{engine-CWTuN3o2.mjs → engine-BvfUx_Jx.mjs} +85 -12
  13. package/dist/engine-BvfUx_Jx.mjs.map +1 -0
  14. package/dist/engine.d.mts +2 -2
  15. package/dist/engine.mjs +3 -3
  16. package/dist/{form-authoring-DCd9XfXf.mjs → form-authoring-BQh40yDb.mjs} +2 -2
  17. package/dist/{form-authoring-DCd9XfXf.mjs.map → form-authoring-BQh40yDb.mjs.map} +1 -1
  18. package/dist/index-8x1Eqlnz.d.mts +741 -0
  19. package/dist/index-8x1Eqlnz.d.mts.map +1 -0
  20. package/dist/{index-SPHf3OoJ.d.mts → index-BDp6S7r9.d.mts} +14 -5
  21. package/dist/index-BDp6S7r9.d.mts.map +1 -0
  22. package/dist/{index-Bp5W_oPa.d.mts → index-biZnRl-h.d.mts} +26 -24
  23. package/dist/index-biZnRl-h.d.mts.map +1 -0
  24. package/dist/{index-CPOQgkTN.d.mts → index-r8HVcn5b.d.mts} +9 -4
  25. package/dist/index-r8HVcn5b.d.mts.map +1 -0
  26. package/dist/lifecycle-DWv5CiSu.d.mts +523 -0
  27. package/dist/lifecycle-DWv5CiSu.d.mts.map +1 -0
  28. package/dist/{memory-thread-repository-acbz6HZJ.mjs → memory-thread-repository-xBZOog_q.mjs} +49 -21
  29. package/dist/memory-thread-repository-xBZOog_q.mjs.map +1 -0
  30. package/dist/{protocol-DATvkr1S.mjs → protocol-DJUP4gc0.mjs} +10 -4
  31. package/dist/protocol-DJUP4gc0.mjs.map +1 -0
  32. package/dist/protocol.d.mts +2 -1
  33. package/dist/protocol.mjs +1 -1
  34. package/dist/{react-3kSE6WtS.mjs → react-CY6N7lVi.mjs} +30 -8
  35. package/dist/react-CY6N7lVi.mjs.map +1 -0
  36. package/dist/react-integration.d.mts +1 -1
  37. package/dist/react-integration.mjs +1 -1
  38. package/dist/react.d.mts +2 -2
  39. package/dist/react.mjs +2 -2
  40. package/dist/{request-context-BEjnaaFr.mjs → request-context-DixY5DYu.mjs} +3 -3
  41. package/dist/request-context-DixY5DYu.mjs.map +1 -0
  42. package/dist/server-agent.d.mts +26 -24
  43. package/dist/server-agent.d.mts.map +1 -1
  44. package/dist/server-agent.mjs +7 -6
  45. package/dist/server-agent.mjs.map +1 -1
  46. package/dist/server-runtime.d.mts +341 -8
  47. package/dist/server-runtime.d.mts.map +1 -1
  48. package/dist/server-runtime.mjs +321 -23
  49. package/dist/server-runtime.mjs.map +1 -1
  50. package/dist/server-tasks.d.mts +1 -1
  51. package/dist/server-tasks.mjs +8 -6
  52. package/dist/server-tasks.mjs.map +1 -1
  53. package/dist/server-tools.d.mts +1 -1
  54. package/dist/server-tools.mjs +1 -1
  55. package/dist/server.d.mts +8 -8
  56. package/dist/server.d.mts.map +1 -1
  57. package/dist/server.mjs +3 -3
  58. package/dist/storage-postgres.d.mts +1 -1
  59. package/dist/{tasks-DIZgr4nD.d.mts → tasks-BWmTMXoK.d.mts} +3 -3
  60. package/dist/{tasks-DIZgr4nD.d.mts.map → tasks-BWmTMXoK.d.mts.map} +1 -1
  61. package/dist/{thread-documents-C3kf0Vds.d.mts → thread-documents-Dvo6XS7o.d.mts} +1 -1
  62. package/dist/{thread-documents-C3kf0Vds.d.mts.map → thread-documents-Dvo6XS7o.d.mts.map} +1 -1
  63. package/dist/{thread-handlers-DZ1WsorO.d.mts → thread-handlers-D8gkLfU6.d.mts} +15 -7
  64. package/dist/{thread-handlers-DZ1WsorO.d.mts.map → thread-handlers-D8gkLfU6.d.mts.map} +1 -1
  65. package/dist/{tools-GDd5_GUh.mjs → tools-TXI8bfzZ.mjs} +28 -9
  66. package/dist/tools-TXI8bfzZ.mjs.map +1 -0
  67. package/dist/ui.css +2 -2
  68. package/dist/ui.d.mts +94 -10
  69. package/dist/ui.d.mts.map +1 -1
  70. package/dist/ui.mjs +561 -203
  71. package/dist/ui.mjs.map +1 -1
  72. package/docs/integration.md +84 -63
  73. package/package.json +25 -19
  74. package/dist/constants-BK1-g6pR.d.mts.map +0 -1
  75. package/dist/controller-proxy-CIDRd8Wu.d.mts.map +0 -1
  76. package/dist/controller-proxy-DY36XFV3.mjs.map +0 -1
  77. package/dist/engine-CWTuN3o2.mjs.map +0 -1
  78. package/dist/index-Bp5W_oPa.d.mts.map +0 -1
  79. package/dist/index-CPOQgkTN.d.mts.map +0 -1
  80. package/dist/index-EDL1V168.d.mts +0 -1257
  81. package/dist/index-EDL1V168.d.mts.map +0 -1
  82. package/dist/index-SPHf3OoJ.d.mts.map +0 -1
  83. package/dist/memory-thread-repository-acbz6HZJ.mjs.map +0 -1
  84. package/dist/protocol-DATvkr1S.mjs.map +0 -1
  85. package/dist/react-3kSE6WtS.mjs.map +0 -1
  86. package/dist/request-context-BEjnaaFr.mjs.map +0 -1
  87. package/dist/tools-GDd5_GUh.mjs.map +0 -1
@@ -7,7 +7,7 @@ storage credentials, logs, and deployment policy.
7
7
 
8
8
  ## Compatibility and release gate
9
9
 
10
- - Node.js 20 or newer and standard Web `Request`/`Response` route handlers.
10
+ - Node.js 22.13.0 or newer and standard Web `Request`/`Response` route handlers.
11
11
  - React and React DOM 19.2 or newer for `/react` and `/ui`.
12
12
  - `@case-framework/survey-core` 0.4.2 or newer within the 0.4 line; the
13
13
  assistant uses its browser-safe `editor/colors` entry.
@@ -25,17 +25,22 @@ import "@case-framework/survey-assistant/ui.css";
25
25
 
26
26
  ## 1. Construct storage, runtime, and Mastra
27
27
 
28
- Parse an injected environment and keep the result as server-only configuration:
28
+ Load YAML in the server-only host, then pass the parsed object and environment to
29
+ the package-owned validator. The package deliberately does not choose a file
30
+ path or read the filesystem:
29
31
 
30
32
  ```ts
31
33
  import { Mastra } from "@mastra/core/mastra";
34
+ import fs from "node:fs";
35
+ import YAML from "yaml";
32
36
  import {
33
37
  createSurveyAssistantRuntime,
34
- parseSurveyAssistantEnvironment,
38
+ parseSurveyAssistantConfigurationDocument,
35
39
  } from "@case-framework/survey-assistant/server/runtime";
36
40
  import { createSurveyAssistantPostgresRuntime } from "@case-framework/survey-assistant/storage/postgres";
37
41
 
38
- const config = parseSurveyAssistantEnvironment(process.env);
42
+ const document = YAML.parse(fs.readFileSync(process.env.SURVEY_ASSISTANT_CONFIG_PATH!, "utf8"));
43
+ const config = parseSurveyAssistantConfigurationDocument(document, process.env);
39
44
  const assistant = createSurveyAssistantRuntime(config);
40
45
  const postgres = createSurveyAssistantPostgresRuntime({
41
46
  store: { id: "survey-assistant", connectionString: process.env.DATABASE_URL! },
@@ -47,48 +52,83 @@ const mastra = new Mastra({
47
52
  });
48
53
  ```
49
54
 
50
- Required provider/storage variables depend on the selected provider. The common
51
- settings are:
52
-
53
- ```dotenv
54
- SURVEY_ASSISTANT_ENABLED=true
55
- SURVEY_ASSISTANT_PROVIDER=openai
56
- SURVEY_ASSISTANT_MODEL=gpt-5.4-nano
57
- # Optional: pin one-shot editor tasks to a separate model.
58
- # SURVEY_ASSISTANT_TASK_MODEL=gpt-5.4-nano
59
- # Optional: use a separate model for memory observation and reflection.
60
- # SURVEY_ASSISTANT_MEMORY_MODEL=gpt-5.4-nano
61
- OPENAI_API_KEY=...
62
- DATABASE_URL=...
63
- ```
55
+ The repository's Survey Editor development host keeps
56
+ `config/survey-assistant.yaml` out of Git. Bootstrap it with:
64
57
 
65
- One deployment uses one provider. For OpenAI, Mistral, and Azure,
66
- `SURVEY_ASSISTANT_MODEL`, `SURVEY_ASSISTANT_MODELS`, `SURVEY_ASSISTANT_TASK_MODEL`,
67
- and `SURVEY_ASSISTANT_MEMORY_MODEL` contain bare model or deployment ids, not
68
- `provider/model` strings. Provider-prefixed values fail at startup.
69
-
70
- LM Studio is available as an opt-in local development provider through Mastra's
71
- built-in OpenAI-compatible model configuration. Set an explicit native model id;
72
- the endpoint defaults to LM Studio's standard local server:
73
-
74
- ```dotenv
75
- SURVEY_ASSISTANT_PROVIDER=lmstudio
76
- SURVEY_ASSISTANT_MODEL=qwen/qwen3.6-27b
77
- SURVEY_ASSISTANT_MODELS=qwen/qwen3.6-27b,qwen/qwen3.6-35b-a3b
78
- # SURVEY_ASSISTANT_LMSTUDIO_BASE_URL=http://127.0.0.1:1234/v1
79
- # SURVEY_ASSISTANT_LMSTUDIO_API_KEY=
58
+ ```bash
59
+ cp apps/survey-editor/config/survey-assistant.example.yaml \
60
+ apps/survey-editor/config/survey-assistant.yaml
80
61
  ```
81
62
 
82
- LM Studio model ids are passed through verbatim and may contain slashes. The
83
- configured model list remains the server-owned allowlist; the integration does
84
- not discover or expose every model loaded in the local server.
63
+ The tracked example is deliberately generic. Treat the copied file as
64
+ machine-local deployment policy and keep all secrets in `.env.local` or the
65
+ deployment secret store.
66
+
67
+ ### Configuration file contract
68
+
69
+ The document selects exactly one active provider. Models are nested beneath
70
+ their provider, retain their array order in the picker, and declare runtime
71
+ roles locally:
72
+
73
+ ```yaml
74
+ version: 1
75
+ activeProvider: openai
76
+ providers:
77
+ openai:
78
+ type: openai
79
+ apiKeyEnv: OPENAI_API_KEY
80
+ options:
81
+ reasoningEffort: low
82
+ reasoningSummary: detailed
83
+ parallelToolCalls: false
84
+ models:
85
+ - id: gpt-5.4-nano
86
+ label: GPT-5.4 Nano
87
+ roles: [chat-picker, chat-default, memory]
88
+ - id: gpt-5.4
89
+ label: GPT-5.4
90
+ roles: [chat-picker]
91
+ ```
85
92
 
86
- `SURVEY_ASSISTANT_MODEL` is the default chat model and
87
- `SURVEY_ASSISTANT_MODELS` is the server-owned chat picker allowlist. When
88
- `SURVEY_ASSISTANT_TASK_MODEL` is omitted, one-shot tasks follow the
89
- server-authorized chat selection; setting it pins all built-in tasks to that
90
- model. The memory model is fixed per runtime and defaults to the configured chat
91
- default. It is shared by Mastra's Observer and Reflector.
93
+ `version` is currently `1`. `activeProvider` references a key under `providers`;
94
+ that key is a local name and does not need to match its `type`. Supported types
95
+ are `openai`, `mistral`, `azure-openai`, and `lmstudio`:
96
+
97
+ - OpenAI and Mistral require `apiKeyEnv`.
98
+ - LM Studio accepts `baseUrl`, `apiKeyEnv`, and `apiKeyOptional`.
99
+ - Azure OpenAI requires `resourceName` and `apiKeyEnv`. Its optional
100
+ `apiVersion` is `v1` or `preview` and defaults to `v1`.
101
+
102
+ For Azure, keep the model's stable application-facing value in `id` and put the
103
+ Azure deployment name in `upstreamModel`. The tracked example contains a full
104
+ Azure provider block. Set `activeProvider: azure` in the deployment copy and
105
+ provide `AZURE_API_KEY` (or change `apiKeyEnv` to the deployment's secret name).
106
+
107
+ `apiKeyEnv` contains an environment-variable name, never a secret value. Only
108
+ the active provider's referenced credentials are required, although every
109
+ provider and model is structurally validated.
110
+
111
+ Exactly one model must have `chat-default`, and it must also have
112
+ `chat-picker`. `task-default` is optional; without it, tasks follow the selected
113
+ chat model. Exactly one `memory` model is required when memory is enabled. A
114
+ model can carry several roles. `upstreamModel` separates a stable application id
115
+ from an Azure deployment or native LM Studio id when necessary. LM Studio ids
116
+ may contain slashes; standard provider and Azure upstream ids must not include a
117
+ provider prefix.
118
+
119
+ Provider options are inherited by every model and can be overridden in a
120
+ model's `options`. Secrets remain in the environment referenced by `apiKeyEnv`.
121
+ Only the active provider's secret is required. `SURVEY_ASSISTANT_ENABLED` is an
122
+ optional operational override; provider, model, role, memory, request-limit, and
123
+ execution policy remains document-owned.
124
+
125
+ The shared option keys are `parallelToolCalls`, `reasoningEffort`,
126
+ `reasoningSummary`, `promptCacheKey`, `promptCacheRetention`, `serviceTier`, and
127
+ `textVerbosity`. Provider validation rejects known-incompatible combinations;
128
+ for example, cache, reasoning-summary, and text-verbosity options are supported
129
+ by OpenAI and Azure OpenAI, while `serviceTier` is supported only by OpenAI.
130
+ Consult the installed provider SDK before choosing provider-specific
131
+ `reasoningEffort` values.
92
132
 
93
133
  The default observational-memory instructions retain user requirements, actual
94
134
  completion state, concrete validation/runtime failures, and actionable recovery
@@ -96,27 +136,8 @@ guidance. Unsupported assistant refusals or speculative claims about tool
96
136
  availability, payload size, or inability to retry are not promoted into durable
97
137
  task constraints.
98
138
 
99
- This same-provider rule applies to the standard runtime. Hosts that genuinely
100
- need custom dynamic or cross-provider model routing can compose the exported
101
- low-level Agent and handler factories instead.
102
-
103
- Optional operational settings have useful defaults:
104
-
105
- ```dotenv
106
- SURVEY_ASSISTANT_MAX_CONCURRENT_REQUESTS=4
107
- SURVEY_ASSISTANT_FIRST_RESPONSE_TIMEOUT_MS=900000
108
- SURVEY_ASSISTANT_IDLE_TIMEOUT_MS=300000
109
- SURVEY_ASSISTANT_MAX_DURATION_MS=3600000
110
- SURVEY_ASSISTANT_MAX_STEPS=48
111
- SURVEY_ASSISTANT_SEND_REASONING=true
112
- SURVEY_ASSISTANT_MEMORY_ENABLED=true
113
- # Optional request policy overrides:
114
- SURVEY_ASSISTANT_MAX_REQUEST_BYTES=20971520
115
- SURVEY_ASSISTANT_MAX_ATTACHMENTS=4
116
- SURVEY_ASSISTANT_MAX_ATTACHMENT_BYTES=5242880
117
- SURVEY_ASSISTANT_MAX_TOTAL_ATTACHMENT_BYTES=12582912
118
- SURVEY_ASSISTANT_MAX_TEXT_PART_CHARS=64000
119
- ```
139
+ `parseSurveyAssistantEnvironment` remains available as a compatibility adapter
140
+ for existing hosts. New integrations should use the versioned document.
120
141
 
121
142
  Chat execution uses three complementary limits. The first-response timeout
122
143
  covers model loading and prompt processing until meaningful output begins. The
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@case-framework/survey-assistant",
3
- "version": "0.2.3",
3
+ "version": "0.4.0",
4
4
  "description": "Shared protocol, engine, and runtime for the CASE survey assistant.",
5
5
  "license": "ISC",
6
6
  "files": [
@@ -90,45 +90,48 @@
90
90
  "clsx": "^2.1.1",
91
91
  "lucide-react": "^1.11.0",
92
92
  "motion": "^12.42.2",
93
- "radix-ui": "^1.6.1",
93
+ "radix-ui": "^1.6.7",
94
94
  "shiki": "^4.3.0",
95
95
  "streamdown": "2.5.0",
96
96
  "tailwind-merge": "^3.5.0",
97
97
  "tw-animate-css": "^1.4.0",
98
98
  "use-stick-to-bottom": "^1.1.6",
99
- "zod": "^4.3.6",
99
+ "zod": "^4.4.3",
100
100
  "@case-framework/ui-localization": "0.2.1"
101
101
  },
102
102
  "devDependencies": {
103
- "@ai-sdk/react": "^4.0.10",
103
+ "@ai-sdk/react": "^4.0.55",
104
104
  "@jest/globals": "30.3.0",
105
- "@mastra/ai-sdk": "^1.6.0",
106
- "@mastra/core": "^1.47.0",
107
- "@mastra/memory": "^1.21.2",
108
- "@mastra/pg": "^1.14.2",
105
+ "@mastra/ai-sdk": "^1.7.1",
106
+ "@mastra/core": "^1.56.0",
107
+ "@mastra/memory": "^1.25.0",
108
+ "@mastra/pg": "^1.19.0",
109
109
  "@tailwindcss/vite": "^4.3.2",
110
110
  "@types/jest": "^30.0.0",
111
111
  "@types/node": "^25.6.0",
112
- "@types/react": "^19.2.14",
113
- "ai": "^7.0.15",
112
+ "@types/react": "^19.2.18",
113
+ "@types/react-test-renderer": "19.1.0",
114
+ "ai": "^7.0.52",
114
115
  "jest": "^30.3.0",
115
- "react": "~19.2.5",
116
+ "react": "~19.2.8",
117
+ "react-dom": "~19.2.8",
118
+ "react-test-renderer": "19.2.8",
116
119
  "ts-jest": "^29.4.9",
117
120
  "tsdown": "^0.21.10",
118
121
  "typescript": "^6.0.3",
119
122
  "vite": "^8.0.10",
120
- "@case-framework/survey-core": "0.6.1"
123
+ "@case-framework/survey-core": "0.6.2"
121
124
  },
122
125
  "peerDependencies": {
123
- "@ai-sdk/react": "^4.0.10",
124
- "@mastra/ai-sdk": "^1.6.0",
125
- "@mastra/core": "^1.47.0",
126
- "@mastra/memory": "^1.21.2",
127
- "@mastra/pg": "^1.14.2",
128
- "ai": "^7.0.15",
126
+ "@ai-sdk/react": "^4.0.55",
127
+ "@mastra/ai-sdk": "^1.7.1",
128
+ "@mastra/core": "^1.56.0",
129
+ "@mastra/memory": "^1.25.0",
130
+ "@mastra/pg": "^1.19.0",
131
+ "ai": "^7.0.52",
129
132
  "react": ">=19.2.0",
130
133
  "react-dom": ">=19.2.0",
131
- "@case-framework/survey-core": "0.6.1"
134
+ "@case-framework/survey-core": "0.6.2"
132
135
  },
133
136
  "peerDependenciesMeta": {
134
137
  "@mastra/ai-sdk": {
@@ -156,6 +159,9 @@
156
159
  "optional": true
157
160
  }
158
161
  },
162
+ "engines": {
163
+ "node": ">=22.13.0"
164
+ },
159
165
  "scripts": {
160
166
  "build": "tsdown && vite build --config vite.ui.config.ts",
161
167
  "test": "jest --config jest.config.cjs --runInBand",
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants-BK1-g6pR.d.mts","names":[],"sources":["../src/server/request-context.ts","../src/server/constants.ts"],"mappings":";;;;;;;UA0BiB,gCAAA;EACf,IAAA;AAAA;AAAA,UAGe,8BAAA;EACf,SAAA;EACA,UAAA;EACA,QAAA;EACA,QAAA;AAAA;AAAA,UAGe,6BAAA;EACf,EAAA;EACA,KAAA,WAAgB,sBAAA;AAAA;AAAA,KAGN,iCAAA;EACN,MAAA;AAAA;EAEA,MAAA;EACA,oBAAA;EACA,mBAAA;AAAA;EAGA,MAAA;EACA,oBAAA;EACA,mBAAA;EACA,mBAAA;AAAA;EAGA,MAAA;EACA,oBAAA;EACA,mBAAA;EACA,gBAAA;EACA,eAAA,EAAiB,KAAA;EACjB,mBAAA;AAAA;AAAA,UAGW,6BAAA;EACf,UAAA,EAAY,gCAAA;EACZ,MAAA;EACA,SAAA,EAAW,eAAA;EACX,QAAA,EAAU,8BAAA;EACV,uBAAA;EACA,kBAAA;EACA,WAAA;EACA,kBAAA;EACA,gBAAA;EACA,kBAAA,GAAqB,iCAAA;EACrB,aAAA,GAAgB,4BAAA;EAChB,gBAAA,GAAmB,sBAAA;EACnB,gBAAA,GAAmB,8BAAA;EACnB,gBAAA,GAAmB,+BAAA;EACnB,cAAA,GAAiB,6BAAA;EACjB,oBAAA,GAAuB,2BAAA;AAAA;AAAA,cAGZ,4BAAA,GAAgC,KAAA,cAAiB,sBAAA;AAAA,cAQjD,0CAAA,GACX,KAAA,cACC,qBAAA;AAAA,cAQU,wCAAA,GACX,KAAA,cACC,2BAAA;AAAA,cAQU,uCAAA;EAA2C,OAAA;EAAA;AAAA;EAItD,OAAA,EAAS,sBAAA;EACT,QAAA,EAAU,qBAAA;AAAA,MACR,iCAAA;AAAA,cAqDS,kCAAA;EAAsC,SAAA;EAAA,QAAA;EAAA,QAAA;EAAA,sBAAA;EAAA,mBAAA;EAAA,gBAAA;EAAA,gBAAA;EAAA,cAAA;EAAA;AAAA;EAWjD,SAAA,EAAW,eAAA;EACX,QAAA,EAAU,8BAAA;EACV,QAAA,EAAU,sBAAA;EACV,sBAAA,GAAyB,qBAAA;EACzB,mBAAA,GAAsB,4BAAA;EACtB,gBAAA,GAAmB,+BAAA;EACnB,gBAAA,GAAmB,8BAAA;EACnB,cAAA,GAAiB,6BAAA;EACjB,oBAAA,GAAuB,2BAAA;AAAA,MACrB,cAAA,CAAe,6BAAA;AAAA,cAuDN,+BAAA,GACX,cAAA,EAAgB,cAAA,CAAe,6BAAA;;;;;;cCtPpB,yBAAA;AAAA,cACA,8BAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"controller-proxy-CIDRd8Wu.d.mts","names":[],"sources":["../src/react/thread-launcher.ts","../src/react/task-client.ts","../src/react/controller.ts","../src/react/controller-proxy.ts"],"mappings":";;;;KAOY,8BAAA,GAAiC,OAAA,CAAQ,IAAA,CAAK,qBAAA;AAAA,UAEzC,2BAAA;EAFL;EAIV,MAAA;EACA,KAAA,GAAQ,UAAA;EALgD;EAOxD,KAAA;EAP2C;EAS3C,SAAA,GAAY,8BAAA;AAAA;AAAA,UAGG,6BAAA;EAZoC;;;;EAiBnD,WAAA,CAAY,KAAA,EAAO,2BAAA,GAA8B,OAAA,CAAQ,qBAAA;AAAA;AAAA,cA6D9C,mCAAA,QAA0C,6BAAA;;;UCtEtC,gCAAA;EACf,GAAA;EACA,UAAA;EACA,UAAA;EACA,QAAA;AAAA;AAAA,UAGe,mCAAA;EACf,IAAA,GAAO,iCAAA;EACP,OAAA;EACA,MAAA,GAAS,WAAA;AAAA;AAAA,UAGM,yBAAA;EACf,cAAA,CACE,KAAA,EAAO,kCAAA,EACP,OAAA,EAAS,0BAAA,EACT,OAAA,GAAU,mCAAA,GACT,OAAA,CAAQ,mCAAA;EACX,gBAAA,CACE,KAAA,EAAO,oCAAA,EACP,OAAA,EAAS,0BAAA,EACT,OAAA,GAAU,mCAAA,GACT,OAAA,CAAQ,qCAAA;EACX,gBAAA,CACE,KAAA,EAAO,oCAAA,EACP,OAAA,EAAS,0BAAA,EACT,OAAA,GAAU,mCAAA,GACT,OAAA,CAAQ,qCAAA;AAAA;AAAA,UAGI,yCAAA;EACf,IAAA,GAAO,iCAAA;EACP,MAAA,GAAS,WAAA;AAAA;AAAA,UAGM,uCAAA;EACf,UAAA;AAAA;AAAA,UAGe,2BAAA;EACf,cAAA,CACE,KAAA,EAAO,kCAAA,EACP,OAAA,EAAS,0BAAA,EACT,OAAA,GAAU,yCAAA,EACV,KAAA,GAAQ,uCAAA,GACP,OAAA,CAAQ,mCAAA;EACX,gBAAA,CACE,KAAA,EAAO,oCAAA,EACP,OAAA,EAAS,0BAAA,EACT,OAAA,GAAU,yCAAA,EACV,KAAA,GAAQ,uCAAA,GACP,OAAA,CAAQ,qCAAA;EACX,gBAAA,CACE,KAAA,EAAO,oCAAA,EACP,OAAA,EAAS,0BAAA,EACT,OAAA,GAAU,yCAAA,EACV,KAAA,GAAQ,uCAAA,GACP,OAAA,CAAQ,qCAAA;AAAA;AAAA,cAGA,+BAAA;EAAmC,GAAA;EAAA,UAAA;EAAA,UAAA;EAAA;AAAA,IAK7C,gCAAA,KAAwC,yBAAA;AAAA,cA8C9B,iCAAA,GACX,OAAA,GAAS,gCAAA,KACR,2BAAA;;;UC1Hc,yBAAA;EACf,WAAA,IAAe,uBAAA;EACf,oBAAA,EAAsB,MAAA,EAAQ,eAAA,GAAkB,iBAAA;EAChD,qBAAA,EAAuB,OAAA,EAAS,eAAA,KAAoB,sBAAA;AAAA;;;UCPrC,2CAAA;EACf,eAAA;AAAA;AAAA,UAGe,+BAAA;EACf,UAAA,EAAY,yBAAA;EACZ,aAAA,CAAc,UAAA,EAAY,yBAAA;AAAA;AAAA,cAWf,oCAAA,GACX,aAAA,QAAqB,yBAAA;EACrB;AAAA,IAEG,2CAAA,KACF,yBAAA;AAAA,cAUU,qCAAA,GACX,OAAA,GAAU,2CAAA,KACT,+BAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"controller-proxy-DY36XFV3.mjs","names":[],"sources":["../src/react/client-error.ts","../src/react/thread-launcher.ts","../src/react/task-client.ts","../src/react/controller-proxy.ts"],"sourcesContent":["import { parseSurveyAssistantError, type SurveyAssistantErrorCode } from \"../protocol\";\n\nexport class SurveyAssistantClientError extends Error {\n readonly code: SurveyAssistantErrorCode;\n\n constructor(code: SurveyAssistantErrorCode, message: string) {\n super(message);\n this.name = \"SurveyAssistantClientError\";\n this.code = code;\n }\n}\n\nexport const readSurveyAssistantJson = async (\n response: Response,\n fallback = \"The assistant request could not be completed.\",\n) => {\n const body = await response.json().catch(() => ({}));\n if (!response.ok) {\n const detail = typeof body?.error === \"string\" ? body.error : fallback;\n const parsed = parseSurveyAssistantError(\n typeof body?.code === \"string\" ? { code: body.code, detail } : detail,\n );\n throw new SurveyAssistantClientError(parsed.code, parsed.detail ?? detail);\n }\n return body;\n};\n","import type {\n SurveyAssistantSnapshot,\n SurveyAssistantThread,\n SurveyEditorUIContext,\n} from \"../protocol\";\nimport type { FileUIPart } from \"ai\";\n\nexport type SurveyAssistantLaunchUIContext = Partial<Omit<SurveyEditorUIContext, \"history\">>;\n\nexport interface SurveyAssistantThreadLaunch {\n /** User-visible prompt submitted as the first message in the new thread. */\n prompt: string;\n files?: FileUIPart[];\n /** Optional manual thread title. The prompt-derived automatic title is used by default. */\n title?: string;\n /** Turn-local editor context merged into the snapshot captured when the prompt is submitted. */\n uiContext?: SurveyAssistantLaunchUIContext;\n}\n\nexport interface SurveyAssistantThreadLauncher {\n /**\n * Creates a new thread and submits its first prompt when a connected panel is ready.\n * Calls made before the panel mounts are queued.\n */\n startThread(input: SurveyAssistantThreadLaunch): Promise<SurveyAssistantThread>;\n}\n\ntype LaunchHandler = (input: SurveyAssistantThreadLaunch) => Promise<SurveyAssistantThread>;\n\ninterface PendingLaunch {\n input: SurveyAssistantThreadLaunch;\n reject(error: unknown): void;\n resolve(thread: SurveyAssistantThread): void;\n}\n\ninterface LauncherState {\n handler: LaunchHandler | null;\n pending: PendingLaunch[];\n draining: boolean;\n}\n\nconst launcherStates = new WeakMap<SurveyAssistantThreadLauncher, LauncherState>();\n\nexport const applySurveyAssistantLaunchUIContext = (\n snapshot: SurveyAssistantSnapshot | null,\n uiContext: SurveyAssistantLaunchUIContext | undefined,\n): SurveyAssistantSnapshot | null =>\n snapshot && uiContext\n ? {\n ...snapshot,\n ui: {\n ...snapshot.ui,\n ...uiContext,\n },\n }\n : snapshot;\n\nconst getLauncherState = (launcher: SurveyAssistantThreadLauncher) => {\n const state = launcherStates.get(launcher);\n if (!state) {\n throw new Error(\n \"The survey assistant thread launcher was not created by createSurveyAssistantThreadLauncher.\",\n );\n }\n return state;\n};\n\nconst drainPendingLaunches = async (state: LauncherState) => {\n if (state.draining) return;\n state.draining = true;\n try {\n while (state.handler && state.pending.length > 0) {\n const pending = state.pending.shift();\n if (!pending) continue;\n try {\n pending.resolve(await state.handler(pending.input));\n } catch (error) {\n pending.reject(error);\n }\n }\n } finally {\n state.draining = false;\n }\n};\n\nexport const createSurveyAssistantThreadLauncher = (): SurveyAssistantThreadLauncher => {\n const state: LauncherState = { handler: null, pending: [], draining: false };\n const launcher: SurveyAssistantThreadLauncher = {\n startThread(input) {\n const prompt = input.prompt.trim();\n if (!prompt && (input.files?.length ?? 0) === 0) {\n return Promise.reject(new Error(\"A survey assistant prompt or attachment is required.\"));\n }\n\n return new Promise((resolve, reject) => {\n state.pending.push({\n input: {\n ...input,\n prompt,\n ...(input.files ? { files: [...input.files] } : {}),\n ...(input.title ? { title: input.title.trim() } : {}),\n },\n reject,\n resolve,\n });\n void drainPendingLaunches(state);\n });\n },\n };\n launcherStates.set(launcher, state);\n return launcher;\n};\n\nexport const connectSurveyAssistantThreadLauncher = (\n launcher: SurveyAssistantThreadLauncher,\n handler: LaunchHandler,\n) => {\n const state = getLauncherState(launcher);\n if (state.handler && state.handler !== handler) {\n throw new Error(\"A survey assistant thread launcher can only control one mounted panel.\");\n }\n state.handler = handler;\n void drainPendingLaunches(state);\n\n return () => {\n if (state.handler === handler) state.handler = null;\n };\n};\n","import {\n surveyAssistantSuggestItemKeyResultSchema,\n surveyAssistantSuggestItemLabelResultSchema,\n surveyAssistantTranslateContentResultSchema,\n type SurveyAssistantSuggestItemKeyInput,\n type SurveyAssistantSuggestItemKeyResult,\n type SurveyAssistantSuggestItemLabelInput,\n type SurveyAssistantSuggestItemLabelResult,\n type SurveyAssistantTaskContext,\n type SurveyAssistantTaskInvocationMode,\n type SurveyAssistantTranslateContentInput,\n type SurveyAssistantTranslateContentResult,\n} from \"../protocol\";\nimport { readSurveyAssistantJson } from \"./client-error\";\n\nexport interface SurveyAssistantTaskClientOptions {\n api?: string;\n getModelId?: () => string | undefined;\n resourceId?: string;\n surveyId?: string;\n}\n\nexport interface SurveyAssistantTaskExecutionOptions {\n mode?: SurveyAssistantTaskInvocationMode;\n modelId?: string;\n signal?: AbortSignal;\n}\n\nexport interface SurveyAssistantTaskClient {\n suggestItemKey(\n input: SurveyAssistantSuggestItemKeyInput,\n context: SurveyAssistantTaskContext,\n options?: SurveyAssistantTaskExecutionOptions,\n ): Promise<SurveyAssistantSuggestItemKeyResult>;\n suggestItemLabel(\n input: SurveyAssistantSuggestItemLabelInput,\n context: SurveyAssistantTaskContext,\n options?: SurveyAssistantTaskExecutionOptions,\n ): Promise<SurveyAssistantSuggestItemLabelResult>;\n translateContent(\n input: SurveyAssistantTranslateContentInput,\n context: SurveyAssistantTaskContext,\n options?: SurveyAssistantTaskExecutionOptions,\n ): Promise<SurveyAssistantTranslateContentResult>;\n}\n\nexport interface SurveyAssistantTaskExecutorRequestOptions {\n mode?: SurveyAssistantTaskInvocationMode;\n signal?: AbortSignal;\n}\n\nexport interface SurveyAssistantTaskExecutorCacheContext {\n cacheScope?: string;\n}\n\nexport interface SurveyAssistantTaskExecutor {\n suggestItemKey(\n input: SurveyAssistantSuggestItemKeyInput,\n context: SurveyAssistantTaskContext,\n options?: SurveyAssistantTaskExecutorRequestOptions,\n cache?: SurveyAssistantTaskExecutorCacheContext,\n ): Promise<SurveyAssistantSuggestItemKeyResult>;\n suggestItemLabel(\n input: SurveyAssistantSuggestItemLabelInput,\n context: SurveyAssistantTaskContext,\n options?: SurveyAssistantTaskExecutorRequestOptions,\n cache?: SurveyAssistantTaskExecutorCacheContext,\n ): Promise<SurveyAssistantSuggestItemLabelResult>;\n translateContent(\n input: SurveyAssistantTranslateContentInput,\n context: SurveyAssistantTaskContext,\n options?: SurveyAssistantTaskExecutorRequestOptions,\n cache?: SurveyAssistantTaskExecutorCacheContext,\n ): Promise<SurveyAssistantTranslateContentResult>;\n}\n\nexport const createSurveyAssistantTaskClient = ({\n api = \"/api/survey-assistant/tasks\",\n getModelId,\n resourceId,\n surveyId,\n}: SurveyAssistantTaskClientOptions = {}): SurveyAssistantTaskClient => {\n const run = async (\n taskId: \"suggest-item-key\" | \"suggest-item-label\" | \"translate-content\",\n input: unknown,\n context: SurveyAssistantTaskContext,\n options?: SurveyAssistantTaskExecutionOptions,\n ) => {\n const modelId = options?.modelId ?? getModelId?.();\n return readSurveyAssistantJson(\n await fetch(api, {\n body: JSON.stringify({\n taskId,\n input,\n context,\n ...(options?.mode ? { mode: options.mode } : {}),\n ...(modelId ? { modelId } : {}),\n ...(resourceId ? { resourceId } : {}),\n ...(surveyId ? { surveyId } : {}),\n }),\n headers: { \"content-type\": \"application/json\" },\n method: \"POST\",\n signal: options?.signal,\n }),\n \"The survey assistant task could not be completed.\",\n );\n };\n\n return {\n async suggestItemKey(input, context, options) {\n return surveyAssistantSuggestItemKeyResultSchema.parse(\n await run(\"suggest-item-key\", input, context, options),\n );\n },\n async suggestItemLabel(input, context, options) {\n return surveyAssistantSuggestItemLabelResultSchema.parse(\n await run(\"suggest-item-label\", input, context, options),\n );\n },\n async translateContent(input, context, options) {\n return surveyAssistantTranslateContentResultSchema.parse(\n await run(\"translate-content\", input, context, options),\n );\n },\n };\n};\n\nexport const createSurveyAssistantTaskExecutor = (\n options: SurveyAssistantTaskClientOptions = {},\n): SurveyAssistantTaskExecutor => {\n const client = createSurveyAssistantTaskClient(options);\n const executionOptions = (\n request?: SurveyAssistantTaskExecutorRequestOptions,\n cache?: SurveyAssistantTaskExecutorCacheContext,\n ): SurveyAssistantTaskExecutionOptions => ({\n mode: request?.mode,\n modelId: cache?.cacheScope,\n signal: request?.signal,\n });\n\n return {\n suggestItemKey: (input, context, request, cache) =>\n client.suggestItemKey(input, context, executionOptions(request, cache)),\n suggestItemLabel: (input, context, request, cache) =>\n client.suggestItemLabel(input, context, executionOptions(request, cache)),\n translateContent: (input, context, request, cache) =>\n client.translateContent(input, context, executionOptions(request, cache)),\n };\n};\n","import type { SurveyApplyResult, SurveyBatchApplyResult, SurveyChangeSet } from \"../protocol\";\nimport type { SurveyAssistantController } from \"./controller\";\n\nexport interface CreateSurveyAssistantControllerProxyOptions {\n notReadyMessage?: string;\n}\n\nexport interface SurveyAssistantControllerBridge {\n controller: SurveyAssistantController;\n setController(controller: SurveyAssistantController | null | undefined): void;\n}\n\nconst failedResult = (change: SurveyChangeSet, message: string): SurveyApplyResult => ({\n status: \"failed\",\n changeId: change.id,\n summary: change.summary,\n message,\n appliedOperations: 0,\n});\n\nexport const createSurveyAssistantControllerProxy = (\n getController: () => SurveyAssistantController | null | undefined,\n {\n notReadyMessage = \"The survey editor is not ready.\",\n }: CreateSurveyAssistantControllerProxyOptions = {},\n): SurveyAssistantController => ({\n getSnapshot: () => getController()?.getSnapshot() ?? null,\n applyAssistantChange: (change) =>\n getController()?.applyAssistantChange?.(change) ?? failedResult(change, notReadyMessage),\n applyAssistantChanges: (changes): SurveyBatchApplyResult =>\n getController()?.applyAssistantChanges?.(changes) ?? {\n results: changes.map((change) => failedResult(change, notReadyMessage)),\n },\n});\n\nexport const createSurveyAssistantControllerBridge = (\n options?: CreateSurveyAssistantControllerProxyOptions,\n): SurveyAssistantControllerBridge => {\n let currentController: SurveyAssistantController | null | undefined;\n return {\n controller: createSurveyAssistantControllerProxy(() => currentController, options),\n setController(controller) {\n currentController = controller;\n },\n };\n};\n"],"mappings":"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"}