@ishlabs/cli 0.17.7 → 0.19.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 +54 -54
- package/dist/commands/ask.d.ts +4 -4
- package/dist/commands/ask.js +66 -66
- package/dist/commands/chat.js +10 -10
- package/dist/commands/config.js +1 -1
- package/dist/commands/docs.js +1 -1
- package/dist/commands/iteration.js +57 -57
- package/dist/commands/mcp.d.ts +23 -0
- package/dist/commands/mcp.js +676 -0
- package/dist/commands/person.d.ts +5 -0
- package/dist/commands/{profile.js → person.js} +197 -162
- package/dist/commands/source.d.ts +6 -2
- package/dist/commands/source.js +35 -30
- package/dist/commands/study-analyze.d.ts +1 -1
- package/dist/commands/study-analyze.js +3 -3
- package/dist/commands/study-participant.d.ts +8 -0
- package/dist/commands/{study-tester.js → study-participant.js} +50 -50
- package/dist/commands/study-run.d.ts +6 -6
- package/dist/commands/study-run.js +341 -290
- package/dist/commands/study.js +106 -72
- package/dist/commands/workspace.js +13 -13
- package/dist/connect.js +5 -5
- package/dist/index.js +6 -4
- package/dist/lib/accessibility-profile.d.ts +1 -1
- package/dist/lib/accessibility-profile.js +1 -1
- package/dist/lib/alias-hydrate.js +4 -4
- package/dist/lib/alias-store.d.ts +5 -5
- package/dist/lib/alias-store.js +8 -8
- package/dist/lib/api-client.d.ts +1 -1
- package/dist/lib/api-client.js +1 -1
- package/dist/lib/billing.d.ts +11 -11
- package/dist/lib/billing.js +16 -16
- package/dist/lib/chat-endpoint-templates.js +1 -1
- package/dist/lib/command-helpers.d.ts +18 -18
- package/dist/lib/command-helpers.js +49 -37
- package/dist/lib/docs.js +570 -387
- package/dist/lib/enums.d.ts +2 -2
- package/dist/lib/enums.js +2 -2
- package/dist/lib/local-sim/browser.d.ts +1 -1
- package/dist/lib/local-sim/browser.js +1 -1
- package/dist/lib/local-sim/debug-report.d.ts +2 -2
- package/dist/lib/local-sim/debug-report.js +3 -3
- package/dist/lib/local-sim/loop.d.ts +5 -5
- package/dist/lib/local-sim/loop.js +38 -38
- package/dist/lib/local-sim/types.d.ts +12 -12
- package/dist/lib/mcp-clients.d.ts +51 -0
- package/dist/lib/mcp-clients.js +175 -0
- package/dist/lib/modality.d.ts +10 -10
- package/dist/lib/modality.js +46 -46
- package/dist/lib/output.d.ts +16 -15
- package/dist/lib/output.js +291 -226
- package/dist/lib/profile-sources.d.ts +64 -16
- package/dist/lib/profile-sources.js +91 -30
- package/dist/lib/skill-content.js +216 -168
- package/dist/lib/study-events.d.ts +3 -3
- package/dist/lib/study-events.js +1 -1
- package/dist/lib/study-inputs.d.ts +11 -1
- package/dist/lib/study-inputs.js +68 -17
- package/dist/lib/study-participants.d.ts +32 -0
- package/dist/lib/study-participants.js +12 -0
- package/dist/lib/types.d.ts +104 -34
- package/package.json +1 -1
- package/dist/commands/profile.d.ts +0 -5
- package/dist/commands/study-tester.d.ts +0 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SSE consumer for the backend's per-study event stream.
|
|
3
3
|
*
|
|
4
|
-
* Used by `study run --wait` to wake up the poll loop as soon as a
|
|
4
|
+
* Used by `study run --wait` to wake up the poll loop as soon as a participant
|
|
5
5
|
* status / interaction event arrives, instead of waiting for the next poll
|
|
6
6
|
* tick. The canonical truth source remains `GET /studies/{id}` — SSE here
|
|
7
7
|
* only shortens the latency between a backend event and the next status
|
|
@@ -26,11 +26,11 @@ export interface StudyEvent {
|
|
|
26
26
|
type: string;
|
|
27
27
|
study_id: string;
|
|
28
28
|
iteration_id?: string | null;
|
|
29
|
-
|
|
29
|
+
participant_id?: string | null;
|
|
30
30
|
interaction_id?: string | null;
|
|
31
31
|
frame_id?: string | null;
|
|
32
32
|
frame_version_id?: string | null;
|
|
33
|
-
|
|
33
|
+
participant_status?: string | null;
|
|
34
34
|
ts: string;
|
|
35
35
|
seq: number;
|
|
36
36
|
payload?: unknown;
|
package/dist/lib/study-events.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SSE consumer for the backend's per-study event stream.
|
|
3
3
|
*
|
|
4
|
-
* Used by `study run --wait` to wake up the poll loop as soon as a
|
|
4
|
+
* Used by `study run --wait` to wake up the poll loop as soon as a participant
|
|
5
5
|
* status / interaction event arrives, instead of waiting for the next poll
|
|
6
6
|
* tick. The canonical truth source remains `GET /studies/{id}` — SSE here
|
|
7
7
|
* only shortens the latency between a backend event and the next status
|
|
@@ -3,13 +3,23 @@
|
|
|
3
3
|
* flags. Mirrors the loose validation style of `src/lib/ask-questions.ts`.
|
|
4
4
|
*/
|
|
5
5
|
import type { Assignment, InterviewQuestion } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Validate a parsed array of assignment objects. Shared by the
|
|
8
|
+
* `--assignments-file` and inline `--assignments` paths so both enforce the
|
|
9
|
+
* same shape: each entry needs a non-empty `name` + `instructions`, and an
|
|
10
|
+
* optional `steps` checklist (validated against backend bounds). Response-only
|
|
11
|
+
* keys like `id` / `step_completion` are tolerated and passed through so a
|
|
12
|
+
* `study get --json` payload round-trips back into a create.
|
|
13
|
+
*/
|
|
14
|
+
export declare function validateAssignmentsArray(parsed: unknown, label: string): Assignment[];
|
|
6
15
|
/**
|
|
7
16
|
* Parse `"Name:Instructions"`. Splits on the first `:`, so colons inside
|
|
8
17
|
* the instructions text are preserved.
|
|
9
18
|
*/
|
|
10
19
|
export declare function parseAssignment(value: string): Assignment;
|
|
11
20
|
/**
|
|
12
|
-
* Read a JSON file containing an array of `{name, instructions}`
|
|
21
|
+
* Read a JSON file containing an array of `{name, instructions, steps?}`
|
|
22
|
+
* entries. `steps` is an optional checklist of `{name, description?}` actions.
|
|
13
23
|
*/
|
|
14
24
|
export declare function loadAssignmentsFile(filePath: string): Assignment[];
|
|
15
25
|
/**
|
package/dist/lib/study-inputs.js
CHANGED
|
@@ -4,6 +4,71 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { readFileSync } from "node:fs";
|
|
6
6
|
import { resolve as resolvePath } from "node:path";
|
|
7
|
+
const STEP_NAME_MAX = 80;
|
|
8
|
+
const STEP_DESC_MAX = 500;
|
|
9
|
+
/**
|
|
10
|
+
* Validate an optional `steps` checklist on one assignment. Mirrors the
|
|
11
|
+
* backend bounds (`AssignmentStep`: name 1–80, description ≤500) so authors get
|
|
12
|
+
* a local error instead of a 422. Returns the cleaned step list.
|
|
13
|
+
*/
|
|
14
|
+
function validateSteps(raw, label) {
|
|
15
|
+
if (!Array.isArray(raw)) {
|
|
16
|
+
throw new Error(`${label}.steps must be an array of {name, description?} objects.`);
|
|
17
|
+
}
|
|
18
|
+
return raw.map((entry, j) => {
|
|
19
|
+
const s = entry;
|
|
20
|
+
if (!s || typeof s !== "object") {
|
|
21
|
+
throw new Error(`${label}.steps[${j}] must be an object with a name.`);
|
|
22
|
+
}
|
|
23
|
+
if (typeof s.name !== "string" || !s.name.trim()) {
|
|
24
|
+
throw new Error(`${label}.steps[${j}].name must be a non-empty string.`);
|
|
25
|
+
}
|
|
26
|
+
if (s.name.length > STEP_NAME_MAX) {
|
|
27
|
+
throw new Error(`${label}.steps[${j}].name must be ≤${STEP_NAME_MAX} characters.`);
|
|
28
|
+
}
|
|
29
|
+
if (s.description !== undefined && s.description !== null) {
|
|
30
|
+
if (typeof s.description !== "string") {
|
|
31
|
+
throw new Error(`${label}.steps[${j}].description must be a string.`);
|
|
32
|
+
}
|
|
33
|
+
if (s.description.length > STEP_DESC_MAX) {
|
|
34
|
+
throw new Error(`${label}.steps[${j}].description must be ≤${STEP_DESC_MAX} characters.`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const step = { name: s.name };
|
|
38
|
+
if (typeof s.description === "string")
|
|
39
|
+
step.description = s.description;
|
|
40
|
+
return step;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Validate a parsed array of assignment objects. Shared by the
|
|
45
|
+
* `--assignments-file` and inline `--assignments` paths so both enforce the
|
|
46
|
+
* same shape: each entry needs a non-empty `name` + `instructions`, and an
|
|
47
|
+
* optional `steps` checklist (validated against backend bounds). Response-only
|
|
48
|
+
* keys like `id` / `step_completion` are tolerated and passed through so a
|
|
49
|
+
* `study get --json` payload round-trips back into a create.
|
|
50
|
+
*/
|
|
51
|
+
export function validateAssignmentsArray(parsed, label) {
|
|
52
|
+
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
53
|
+
throw new Error(`${label} must be a non-empty JSON array.`);
|
|
54
|
+
}
|
|
55
|
+
for (let i = 0; i < parsed.length; i++) {
|
|
56
|
+
const a = parsed[i];
|
|
57
|
+
if (!a || typeof a !== "object") {
|
|
58
|
+
throw new Error(`assignments[${i}] must be an object with name + instructions.`);
|
|
59
|
+
}
|
|
60
|
+
if (typeof a.name !== "string" || !a.name.trim()) {
|
|
61
|
+
throw new Error(`assignments[${i}].name must be a non-empty string.`);
|
|
62
|
+
}
|
|
63
|
+
if (typeof a.instructions !== "string" || !a.instructions.trim()) {
|
|
64
|
+
throw new Error(`assignments[${i}].instructions must be a non-empty string.`);
|
|
65
|
+
}
|
|
66
|
+
if (a.steps !== undefined && a.steps !== null) {
|
|
67
|
+
a.steps = validateSteps(a.steps, `assignments[${i}]`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return parsed;
|
|
71
|
+
}
|
|
7
72
|
/**
|
|
8
73
|
* Parse `"Name:Instructions"`. Splits on the first `:`, so colons inside
|
|
9
74
|
* the instructions text are preserved.
|
|
@@ -24,7 +89,8 @@ export function parseAssignment(value) {
|
|
|
24
89
|
return { name, instructions };
|
|
25
90
|
}
|
|
26
91
|
/**
|
|
27
|
-
* Read a JSON file containing an array of `{name, instructions}`
|
|
92
|
+
* Read a JSON file containing an array of `{name, instructions, steps?}`
|
|
93
|
+
* entries. `steps` is an optional checklist of `{name, description?}` actions.
|
|
28
94
|
*/
|
|
29
95
|
export function loadAssignmentsFile(filePath) {
|
|
30
96
|
let raw;
|
|
@@ -41,22 +107,7 @@ export function loadAssignmentsFile(filePath) {
|
|
|
41
107
|
catch {
|
|
42
108
|
throw new Error(`Invalid JSON in assignments file: ${filePath}`);
|
|
43
109
|
}
|
|
44
|
-
|
|
45
|
-
throw new Error(`Assignments file must be a non-empty JSON array: ${filePath}`);
|
|
46
|
-
}
|
|
47
|
-
for (let i = 0; i < parsed.length; i++) {
|
|
48
|
-
const a = parsed[i];
|
|
49
|
-
if (!a || typeof a !== "object") {
|
|
50
|
-
throw new Error(`assignments[${i}] must be an object with name + instructions.`);
|
|
51
|
-
}
|
|
52
|
-
if (typeof a.name !== "string" || !a.name.trim()) {
|
|
53
|
-
throw new Error(`assignments[${i}].name must be a non-empty string.`);
|
|
54
|
-
}
|
|
55
|
-
if (typeof a.instructions !== "string" || !a.instructions.trim()) {
|
|
56
|
-
throw new Error(`assignments[${i}].instructions must be a non-empty string.`);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return parsed;
|
|
110
|
+
return validateAssignmentsArray(parsed, `Assignments file ${filePath}`);
|
|
60
111
|
}
|
|
61
112
|
/**
|
|
62
113
|
* Parse a plain question text into a default text-typed, after-timed
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrapper for the post-split `GET /studies/{id}/participants` endpoint.
|
|
3
|
+
*
|
|
4
|
+
* Returns a flat list of participants for one study with an `iteration_id`
|
|
5
|
+
* discriminator on each row. Each row carries the rich per-participant graph
|
|
6
|
+
* (person, interactions[], participant_summary, interview_answers, …) that
|
|
7
|
+
* used to be embedded under `study.iterations[*].participants[*]` on the
|
|
8
|
+
* legacy `GET /studies/{id}` response.
|
|
9
|
+
*/
|
|
10
|
+
import type { ApiClient } from "./api-client.js";
|
|
11
|
+
import type { Participant } from "./types.js";
|
|
12
|
+
export interface StudyParticipant extends Participant {
|
|
13
|
+
person?: {
|
|
14
|
+
id?: string;
|
|
15
|
+
name?: string;
|
|
16
|
+
};
|
|
17
|
+
interactions?: unknown[];
|
|
18
|
+
participant_summary?: Record<string, unknown> | null;
|
|
19
|
+
interview_answers?: Array<{
|
|
20
|
+
question_id?: string;
|
|
21
|
+
answer?: unknown;
|
|
22
|
+
}>;
|
|
23
|
+
participant_files?: unknown[];
|
|
24
|
+
participant_assignments?: unknown[];
|
|
25
|
+
conversation_id?: string | null;
|
|
26
|
+
error_message?: string | null;
|
|
27
|
+
error_kind?: string | null;
|
|
28
|
+
[k: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
export declare function fetchStudyParticipants(client: ApiClient, studyId: string, opts?: {
|
|
31
|
+
timeout?: number;
|
|
32
|
+
}): Promise<StudyParticipant[]>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrapper for the post-split `GET /studies/{id}/participants` endpoint.
|
|
3
|
+
*
|
|
4
|
+
* Returns a flat list of participants for one study with an `iteration_id`
|
|
5
|
+
* discriminator on each row. Each row carries the rich per-participant graph
|
|
6
|
+
* (person, interactions[], participant_summary, interview_answers, …) that
|
|
7
|
+
* used to be embedded under `study.iterations[*].participants[*]` on the
|
|
8
|
+
* legacy `GET /studies/{id}` response.
|
|
9
|
+
*/
|
|
10
|
+
export async function fetchStudyParticipants(client, studyId, opts) {
|
|
11
|
+
return await client.get(`/studies/${studyId}/participants`, undefined, opts);
|
|
12
|
+
}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -54,10 +54,46 @@ export interface SecretUpdateInput {
|
|
|
54
54
|
export interface SecretBatchCreateInput {
|
|
55
55
|
secrets: SecretCreateInput[];
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* One atomic, author-supplied action inside an assignment's checklist
|
|
59
|
+
* (e.g. "Add to cart"). Authored via the JSON forms of `study create/update`
|
|
60
|
+
* (`--assignments-file` / `--assignments`) — only for `interactive` and
|
|
61
|
+
* `external_chatbot chat` modalities; the backend rejects steps elsewhere.
|
|
62
|
+
*/
|
|
63
|
+
export interface AssignmentStep {
|
|
64
|
+
/** Response-only server slug (e.g. "add-to-cart"); omitted on write. */
|
|
65
|
+
id?: string;
|
|
66
|
+
/** 1–80 chars. */
|
|
67
|
+
name: string;
|
|
68
|
+
/** ≤500 chars. */
|
|
69
|
+
description?: string;
|
|
70
|
+
}
|
|
71
|
+
/** One sampled participant who failed a step, with the verifier's reason. */
|
|
72
|
+
export interface SampleFailure {
|
|
73
|
+
participant_id: string;
|
|
74
|
+
reason: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Response-only per-step completion rollup, populated by the backend after a
|
|
78
|
+
* run grades each step per participant. Ignored on write.
|
|
79
|
+
*/
|
|
80
|
+
export interface StepCompletion {
|
|
81
|
+
step_id: string;
|
|
82
|
+
name: string;
|
|
83
|
+
description?: string;
|
|
84
|
+
total: number;
|
|
85
|
+
passed: number;
|
|
86
|
+
rate?: number | null;
|
|
87
|
+
sample_failures?: SampleFailure[];
|
|
88
|
+
}
|
|
57
89
|
export interface Assignment {
|
|
58
90
|
id?: string;
|
|
59
91
|
name: string;
|
|
60
92
|
instructions: string;
|
|
93
|
+
/** Optional checklist authored on write; resolved with `id` on read. */
|
|
94
|
+
steps?: AssignmentStep[];
|
|
95
|
+
/** Response-only completion rollup; ignored on write. */
|
|
96
|
+
step_completion?: StepCompletion[];
|
|
61
97
|
}
|
|
62
98
|
export interface InterviewQuestion {
|
|
63
99
|
id?: string;
|
|
@@ -119,7 +155,6 @@ export interface Iteration {
|
|
|
119
155
|
description?: string;
|
|
120
156
|
label?: string;
|
|
121
157
|
details?: Record<string, unknown>;
|
|
122
|
-
testers?: Tester[];
|
|
123
158
|
created_at: string;
|
|
124
159
|
updated_at: string;
|
|
125
160
|
}
|
|
@@ -134,39 +169,75 @@ export interface IterationUpdateInput {
|
|
|
134
169
|
details?: Record<string, unknown>;
|
|
135
170
|
label?: string;
|
|
136
171
|
}
|
|
137
|
-
export interface
|
|
172
|
+
export interface Person {
|
|
138
173
|
id: string;
|
|
139
174
|
name: string;
|
|
140
175
|
[key: string]: unknown;
|
|
141
176
|
}
|
|
142
|
-
export type
|
|
143
|
-
export type
|
|
144
|
-
|
|
177
|
+
export type AttachmentKind = "text_file" | "audio" | "image";
|
|
178
|
+
export type AttachmentStatus = "pending_upload" | "uploaded" | "transcribing" | "processing" | "processed" | "failed";
|
|
179
|
+
/** How a file relates to a participant profile (`identity` is reserved). */
|
|
180
|
+
export type AttachmentRelation = "seed" | "attached";
|
|
181
|
+
/** Single attachment row returned by GET /people/attachments/{id}. */
|
|
182
|
+
export interface Attachment {
|
|
145
183
|
id: string;
|
|
146
184
|
product_id: string;
|
|
147
|
-
kind:
|
|
148
|
-
status:
|
|
149
|
-
|
|
185
|
+
kind: AttachmentKind;
|
|
186
|
+
status: AttachmentStatus;
|
|
187
|
+
file_name: string;
|
|
150
188
|
content_type: string;
|
|
189
|
+
file_size_bytes?: number | null;
|
|
151
190
|
extracted_text_length?: number | null;
|
|
191
|
+
description?: string | null;
|
|
152
192
|
error?: string | null;
|
|
193
|
+
relations: AttachmentRelation[];
|
|
153
194
|
created_at: string;
|
|
154
195
|
}
|
|
155
|
-
export interface
|
|
156
|
-
|
|
196
|
+
export interface InitiateAttachmentUploadResponse {
|
|
197
|
+
attachment_id: string;
|
|
157
198
|
signed_url: string;
|
|
158
199
|
upload_token: string;
|
|
159
200
|
}
|
|
201
|
+
export type SourceKind = AttachmentKind;
|
|
202
|
+
export type SourceStatus = AttachmentStatus;
|
|
203
|
+
export type PersonSource = Attachment;
|
|
204
|
+
export type InitiateSourceUploadResponse = InitiateAttachmentUploadResponse;
|
|
160
205
|
export interface ProposeCountResponse {
|
|
161
206
|
proposed_count: number;
|
|
162
207
|
rationale: string;
|
|
163
208
|
}
|
|
164
|
-
export interface
|
|
209
|
+
export interface GeneratePeopleRequest {
|
|
165
210
|
product_id: string;
|
|
166
211
|
description?: string;
|
|
167
212
|
source_upload_ids?: string[];
|
|
168
213
|
count?: number;
|
|
169
214
|
}
|
|
215
|
+
export type GenerationJobStatus = "queued" | "processing" | "completed" | "failed";
|
|
216
|
+
export interface CreateGenerationJobRequest {
|
|
217
|
+
product_id: string;
|
|
218
|
+
description?: string;
|
|
219
|
+
source_upload_ids?: string[];
|
|
220
|
+
count?: number;
|
|
221
|
+
}
|
|
222
|
+
export interface GenerationJob {
|
|
223
|
+
id: string;
|
|
224
|
+
status: GenerationJobStatus;
|
|
225
|
+
progress_message: string | null;
|
|
226
|
+
person_ids: string[];
|
|
227
|
+
error: string | null;
|
|
228
|
+
created_at: string;
|
|
229
|
+
updated_at: string;
|
|
230
|
+
}
|
|
231
|
+
/** One scenario the job grounded in a real reaction (GET /people/{id}/scenarios). */
|
|
232
|
+
export interface ProfileScenario {
|
|
233
|
+
source: string;
|
|
234
|
+
scenario_prompt: string;
|
|
235
|
+
text: string;
|
|
236
|
+
raw_response?: {
|
|
237
|
+
evidence_quote?: string;
|
|
238
|
+
} & Record<string, unknown>;
|
|
239
|
+
[key: string]: unknown;
|
|
240
|
+
}
|
|
170
241
|
export interface GeneratedProfile {
|
|
171
242
|
id: string;
|
|
172
243
|
name: string;
|
|
@@ -243,30 +314,30 @@ export interface EvidenceTraceResponse {
|
|
|
243
314
|
raw_response: Record<string, unknown> | null;
|
|
244
315
|
created_at: string;
|
|
245
316
|
}
|
|
246
|
-
export interface
|
|
317
|
+
export interface Participant {
|
|
247
318
|
id: string;
|
|
248
319
|
iteration_id: string;
|
|
249
|
-
|
|
320
|
+
person_id: string;
|
|
250
321
|
instance_name?: string;
|
|
251
322
|
instance_number?: number;
|
|
252
323
|
status: string;
|
|
253
324
|
language?: string;
|
|
254
325
|
platform?: string;
|
|
255
|
-
|
|
326
|
+
participant_type?: string;
|
|
256
327
|
viewport_width?: number;
|
|
257
328
|
viewport_height?: number;
|
|
258
329
|
created_at: string;
|
|
259
330
|
}
|
|
260
|
-
export interface
|
|
261
|
-
|
|
331
|
+
export interface ParticipantCreateInput {
|
|
332
|
+
person_id: string;
|
|
262
333
|
instance_name?: string;
|
|
263
334
|
status?: string;
|
|
264
335
|
language?: string;
|
|
265
336
|
platform?: string;
|
|
266
|
-
|
|
337
|
+
participant_type?: string;
|
|
267
338
|
}
|
|
268
339
|
export interface SimulationStartResponse {
|
|
269
|
-
|
|
340
|
+
participant_id: string;
|
|
270
341
|
study_id: string;
|
|
271
342
|
job_id: string | null;
|
|
272
343
|
message: string;
|
|
@@ -296,7 +367,6 @@ export interface SimulationConfig {
|
|
|
296
367
|
id: string;
|
|
297
368
|
name: string;
|
|
298
369
|
model_settings?: Record<string, unknown>;
|
|
299
|
-
simulation_settings?: Record<string, unknown>;
|
|
300
370
|
prompts?: Record<string, unknown>;
|
|
301
371
|
outputs?: Record<string, unknown>;
|
|
302
372
|
source_type?: string;
|
|
@@ -329,14 +399,14 @@ export interface InterviewAnswer {
|
|
|
329
399
|
/**
|
|
330
400
|
* Pattern B — drill-in subset for a follow-up ask round.
|
|
331
401
|
*
|
|
332
|
-
* Filters the new round's
|
|
402
|
+
* Filters the new round's participants to those who picked
|
|
333
403
|
* `picked_variant_id` on the 1-indexed prior `round`. Mirrors the
|
|
334
|
-
* backend's `
|
|
404
|
+
* backend's `ParticipantSubset` model. Only valid on follow-up rounds —
|
|
335
405
|
* round 1 has no prior round to filter against. The backend rejects
|
|
336
406
|
* unresolvable subsets with a 422 carrying
|
|
337
|
-
* `error_kind: "
|
|
407
|
+
* `error_kind: "participant_subset_invalid"`.
|
|
338
408
|
*/
|
|
339
|
-
export interface
|
|
409
|
+
export interface ParticipantSubset {
|
|
340
410
|
round: number;
|
|
341
411
|
picked_variant_id: string;
|
|
342
412
|
}
|
|
@@ -346,13 +416,13 @@ export interface AskRoundInput {
|
|
|
346
416
|
wants_pick?: boolean;
|
|
347
417
|
wants_ratings?: boolean;
|
|
348
418
|
questions?: InterviewQuestion[];
|
|
349
|
-
|
|
419
|
+
participant_subset?: ParticipantSubset;
|
|
350
420
|
}
|
|
351
421
|
export interface AskCreateInput {
|
|
352
422
|
name: string;
|
|
353
423
|
description?: string;
|
|
354
424
|
language?: string;
|
|
355
|
-
|
|
425
|
+
person_ids: string[];
|
|
356
426
|
first_round: AskRoundInput;
|
|
357
427
|
dispatch?: boolean;
|
|
358
428
|
}
|
|
@@ -361,20 +431,20 @@ export interface AskUpdateInput {
|
|
|
361
431
|
description?: string;
|
|
362
432
|
is_archived?: boolean;
|
|
363
433
|
}
|
|
364
|
-
export interface
|
|
365
|
-
|
|
366
|
-
|
|
434
|
+
export interface AddPeopleInput {
|
|
435
|
+
person_ids: string[];
|
|
436
|
+
dispatch_into_round_id: string;
|
|
367
437
|
backfill_prior_rounds?: boolean;
|
|
368
438
|
}
|
|
369
439
|
export interface AddRoundQuestionsInput {
|
|
370
440
|
questions: InterviewQuestion[];
|
|
371
441
|
redispatch_all?: boolean;
|
|
372
442
|
}
|
|
373
|
-
export interface
|
|
443
|
+
export interface AskParticipant {
|
|
374
444
|
id: string;
|
|
375
445
|
ask_id?: string;
|
|
376
|
-
|
|
377
|
-
|
|
446
|
+
person_id?: string;
|
|
447
|
+
person?: Record<string, unknown> | null;
|
|
378
448
|
instance_name?: string;
|
|
379
449
|
status?: string;
|
|
380
450
|
[key: string]: unknown;
|
|
@@ -382,7 +452,7 @@ export interface AskAudienceTester {
|
|
|
382
452
|
export interface AskResponseModel {
|
|
383
453
|
id: string;
|
|
384
454
|
ask_round_id: string;
|
|
385
|
-
|
|
455
|
+
participant_id: string;
|
|
386
456
|
comment?: string | null;
|
|
387
457
|
variant_pick_id?: string | null;
|
|
388
458
|
pick_confidence?: number | null;
|
|
@@ -418,7 +488,7 @@ export interface Ask {
|
|
|
418
488
|
description?: string | null;
|
|
419
489
|
is_archived: boolean;
|
|
420
490
|
status?: AskStatus;
|
|
421
|
-
|
|
491
|
+
participants: AskParticipant[];
|
|
422
492
|
rounds: AskRound[];
|
|
423
493
|
created_at: string;
|
|
424
494
|
updated_at: string;
|
|
@@ -431,7 +501,7 @@ export interface AskListItem {
|
|
|
431
501
|
description?: string | null;
|
|
432
502
|
is_archived: boolean;
|
|
433
503
|
status?: AskStatus;
|
|
434
|
-
|
|
504
|
+
participant_count: number;
|
|
435
505
|
round_count: number;
|
|
436
506
|
last_round_at?: string | null;
|
|
437
507
|
created_at: string;
|
package/package.json
CHANGED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ish study tester — Inspect and manage testers (low-level; usually
|
|
3
|
-
* created via `ish study run`).
|
|
4
|
-
*
|
|
5
|
-
* Default action: `ish study tester <id>` shows tester details and results.
|
|
6
|
-
*/
|
|
7
|
-
import type { Command } from "commander";
|
|
8
|
-
export declare function attachStudyTesterCommands(study: Command): void;
|