@case-framework/survey-assistant 0.3.0 → 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.
- package/README.md +12 -4
- package/dist/capabilities-default.d.mts +1 -1
- package/dist/capabilities-default.mjs +1 -1
- package/dist/{constants-DrGZXtQf.d.mts → constants-k1b_evIb.d.mts} +5 -2
- package/dist/constants-k1b_evIb.d.mts.map +1 -0
- package/dist/{controller-proxy-CpkQRezb.mjs → controller-proxy-jWIPOZAv.mjs} +17 -8
- package/dist/controller-proxy-jWIPOZAv.mjs.map +1 -0
- package/dist/{controller-proxy-DmBdzqKs.d.mts → controller-proxy-quQjtA7j.d.mts} +2 -2
- package/dist/{controller-proxy-DmBdzqKs.d.mts.map → controller-proxy-quQjtA7j.d.mts.map} +1 -1
- package/dist/{engine-CWTuN3o2.mjs → engine-BvfUx_Jx.mjs} +85 -12
- package/dist/engine-BvfUx_Jx.mjs.map +1 -0
- package/dist/engine.d.mts +2 -2
- package/dist/engine.mjs +3 -3
- package/dist/{form-authoring-DCd9XfXf.mjs → form-authoring-BQh40yDb.mjs} +2 -2
- package/dist/{form-authoring-DCd9XfXf.mjs.map → form-authoring-BQh40yDb.mjs.map} +1 -1
- package/dist/{index-D4OitUg4.d.mts → index-8x1Eqlnz.d.mts} +4 -1
- package/dist/index-8x1Eqlnz.d.mts.map +1 -0
- package/dist/{index-Dxgg0-D_.d.mts → index-BDp6S7r9.d.mts} +11 -5
- package/dist/index-BDp6S7r9.d.mts.map +1 -0
- package/dist/{index-DZk20e3k.d.mts → index-biZnRl-h.d.mts} +3 -3
- package/dist/{index-DZk20e3k.d.mts.map → index-biZnRl-h.d.mts.map} +1 -1
- package/dist/{index-Bo4dHAo8.d.mts → index-r8HVcn5b.d.mts} +8 -4
- package/dist/index-r8HVcn5b.d.mts.map +1 -0
- package/dist/{memory-thread-repository-acbz6HZJ.mjs → memory-thread-repository-xBZOog_q.mjs} +49 -21
- package/dist/memory-thread-repository-xBZOog_q.mjs.map +1 -0
- package/dist/{protocol-DATvkr1S.mjs → protocol-DJUP4gc0.mjs} +10 -4
- package/dist/protocol-DJUP4gc0.mjs.map +1 -0
- package/dist/protocol.d.mts +1 -1
- package/dist/protocol.mjs +1 -1
- package/dist/{react-Br5YE8H-.mjs → react-CY6N7lVi.mjs} +25 -5
- package/dist/react-CY6N7lVi.mjs.map +1 -0
- package/dist/react-integration.d.mts +1 -1
- package/dist/react-integration.mjs +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.mjs +2 -2
- package/dist/{request-context-BEjnaaFr.mjs → request-context-DixY5DYu.mjs} +3 -3
- package/dist/request-context-DixY5DYu.mjs.map +1 -0
- package/dist/server-agent.d.mts +4 -4
- package/dist/server-agent.d.mts.map +1 -1
- package/dist/server-agent.mjs +4 -3
- package/dist/server-agent.mjs.map +1 -1
- package/dist/server-runtime.d.mts +340 -7
- package/dist/server-runtime.d.mts.map +1 -1
- package/dist/server-runtime.mjs +321 -23
- package/dist/server-runtime.mjs.map +1 -1
- package/dist/server-tasks.d.mts +1 -1
- package/dist/server-tasks.mjs +5 -4
- package/dist/server-tasks.mjs.map +1 -1
- package/dist/server-tools.d.mts +1 -1
- package/dist/server-tools.mjs +1 -1
- package/dist/server.d.mts +6 -6
- package/dist/server.d.mts.map +1 -1
- package/dist/server.mjs +2 -2
- package/dist/{tasks-DQgL449A.d.mts → tasks-BWmTMXoK.d.mts} +3 -3
- package/dist/{tasks-DQgL449A.d.mts.map → tasks-BWmTMXoK.d.mts.map} +1 -1
- package/dist/{thread-handlers-CeYl45xG.d.mts → thread-handlers-D8gkLfU6.d.mts} +13 -5
- package/dist/{thread-handlers-CeYl45xG.d.mts.map → thread-handlers-D8gkLfU6.d.mts.map} +1 -1
- package/dist/{tools-Dg9HZrYU.mjs → tools-TXI8bfzZ.mjs} +25 -6
- package/dist/{tools-Dg9HZrYU.mjs.map → tools-TXI8bfzZ.mjs.map} +1 -1
- package/dist/ui.css +1 -1
- package/dist/ui.d.mts +3 -3
- package/dist/ui.d.mts.map +1 -1
- package/dist/ui.mjs +370 -127
- package/dist/ui.mjs.map +1 -1
- package/docs/integration.md +83 -62
- package/package.json +3 -3
- package/dist/constants-DrGZXtQf.d.mts.map +0 -1
- package/dist/controller-proxy-CpkQRezb.mjs.map +0 -1
- package/dist/engine-CWTuN3o2.mjs.map +0 -1
- package/dist/index-Bo4dHAo8.d.mts.map +0 -1
- package/dist/index-D4OitUg4.d.mts.map +0 -1
- package/dist/index-Dxgg0-D_.d.mts.map +0 -1
- package/dist/memory-thread-repository-acbz6HZJ.mjs.map +0 -1
- package/dist/protocol-DATvkr1S.mjs.map +0 -1
- package/dist/react-Br5YE8H-.mjs.map +0 -1
- package/dist/request-context-BEjnaaFr.mjs.map +0 -1
package/docs/integration.md
CHANGED
|
@@ -25,17 +25,22 @@ import "@case-framework/survey-assistant/ui.css";
|
|
|
25
25
|
|
|
26
26
|
## 1. Construct storage, runtime, and Mastra
|
|
27
27
|
|
|
28
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
51
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
`
|
|
87
|
-
|
|
88
|
-
`
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
100
|
-
|
|
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.
|
|
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": [
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"tsdown": "^0.21.10",
|
|
121
121
|
"typescript": "^6.0.3",
|
|
122
122
|
"vite": "^8.0.10",
|
|
123
|
-
"@case-framework/survey-core": "0.6.
|
|
123
|
+
"@case-framework/survey-core": "0.6.2"
|
|
124
124
|
},
|
|
125
125
|
"peerDependencies": {
|
|
126
126
|
"@ai-sdk/react": "^4.0.55",
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
"ai": "^7.0.52",
|
|
132
132
|
"react": ">=19.2.0",
|
|
133
133
|
"react-dom": ">=19.2.0",
|
|
134
|
-
"@case-framework/survey-core": "0.6.
|
|
134
|
+
"@case-framework/survey-core": "0.6.2"
|
|
135
135
|
},
|
|
136
136
|
"peerDependenciesMeta": {
|
|
137
137
|
"@mastra/ai-sdk": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants-DrGZXtQf.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-CpkQRezb.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 model used for the opening assistant turn. */\n modelId?: string;\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.modelId ? { modelId: input.modelId.trim() } : {}),\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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"}
|