@gitterm/sdk 0.2.0 → 0.2.2
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 +6 -0
- package/dist/direct/index.js +38 -5
- package/dist/types.d.ts +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -517,6 +517,12 @@ remain. The exported types are `AgentPermissionRequest`, `AgentQuestionRequest`,
|
|
|
517
517
|
**labels** keyed by question `key`, or one free-text string when `custom` is true:
|
|
518
518
|
`{ type: "question", answers: { [question.key]: string[] } }`. Every question needs an entry.
|
|
519
519
|
Or dismiss all of them with `{ type: "question", reject: true }`.
|
|
520
|
+
`custom` defaults to true, matching OpenCode; false only when the agent sets it.
|
|
521
|
+
Questions with `options: []` accept free-text answers when `custom` is true.
|
|
522
|
+
|
|
523
|
+
Question options are normalised at the runtime boundary: labels and descriptions are trimmed,
|
|
524
|
+
OpenCode's copied "Type your own answer" entry is removed and enables `custom: true`, and
|
|
525
|
+
duplicate and blank labels are dropped. Hosted users need the API redeployed for this to take effect.
|
|
520
526
|
|
|
521
527
|
The quick start above shows a complete relay. Rejecting a permission or dismissing a question
|
|
522
528
|
ends the turn: OpenCode records a failed tool call and the run finishes. A run left
|
package/dist/direct/index.js
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { createOpencodeClient as createOpencodeClient2 } from "@opencode-ai/sdk";
|
|
4
4
|
|
|
5
|
+
// ../agent-runtime/src/normalize.ts
|
|
6
|
+
var OPENCODE_CUSTOM_OPTION_LABEL = /^type your own answer\W*$/i;
|
|
7
|
+
function normalizeQuestion(question) {
|
|
8
|
+
const options = [];
|
|
9
|
+
const labels = new Set;
|
|
10
|
+
let changed = false;
|
|
11
|
+
let custom = question.custom;
|
|
12
|
+
for (const option of question.options) {
|
|
13
|
+
const label = option.label.trim();
|
|
14
|
+
const description = option.description.trim();
|
|
15
|
+
if (OPENCODE_CUSTOM_OPTION_LABEL.test(label)) {
|
|
16
|
+
custom = true;
|
|
17
|
+
changed = true;
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (!label || labels.has(label)) {
|
|
21
|
+
changed = true;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
labels.add(label);
|
|
25
|
+
if (label !== option.label || description !== option.description) {
|
|
26
|
+
changed = true;
|
|
27
|
+
options.push({ ...option, label, description });
|
|
28
|
+
} else {
|
|
29
|
+
options.push(option);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return changed ? { ...question, options, custom } : question;
|
|
33
|
+
}
|
|
34
|
+
|
|
5
35
|
// ../agent-runtime/src/opencode.ts
|
|
6
36
|
import { createOpencodeClient } from "@opencode-ai/sdk";
|
|
7
37
|
|
|
@@ -426,7 +456,7 @@ function questionRequest(raw) {
|
|
|
426
456
|
kind: "question",
|
|
427
457
|
createdAt: null,
|
|
428
458
|
toolCallId: asString(tool.callID),
|
|
429
|
-
questions: questions.map((question, index) => ({
|
|
459
|
+
questions: questions.map((question, index) => normalizeQuestion({
|
|
430
460
|
key: `q${index}`,
|
|
431
461
|
header: asString(question.header) ?? `Question ${index + 1}`,
|
|
432
462
|
question: asString(question.question) ?? "",
|
|
@@ -435,7 +465,7 @@ function questionRequest(raw) {
|
|
|
435
465
|
description: asString(option.description) ?? ""
|
|
436
466
|
})),
|
|
437
467
|
multiple: question.multiple === true,
|
|
438
|
-
custom: question.custom
|
|
468
|
+
custom: question.custom !== false
|
|
439
469
|
}))
|
|
440
470
|
};
|
|
441
471
|
}
|
|
@@ -714,7 +744,7 @@ function formRequest(raw) {
|
|
|
714
744
|
toolCallId: asString(tool.id) ?? asString(tool.callID),
|
|
715
745
|
questions: fields.map((field, index) => {
|
|
716
746
|
const key = asString(field.key) ?? `q${index}`;
|
|
717
|
-
return {
|
|
747
|
+
return normalizeQuestion({
|
|
718
748
|
key,
|
|
719
749
|
header: asString(field.title) ?? key,
|
|
720
750
|
question: asString(field.description) ?? asString(field.title) ?? key,
|
|
@@ -728,8 +758,8 @@ function formRequest(raw) {
|
|
|
728
758
|
};
|
|
729
759
|
}),
|
|
730
760
|
multiple: field.type === "multiselect",
|
|
731
|
-
custom: field.custom
|
|
732
|
-
};
|
|
761
|
+
custom: field.custom !== false
|
|
762
|
+
});
|
|
733
763
|
})
|
|
734
764
|
};
|
|
735
765
|
}
|
|
@@ -842,6 +872,9 @@ function questionAnswers(request, answers) {
|
|
|
842
872
|
throw new Error(`Answers must cover exactly the question keys ${JSON.stringify(keys)}`);
|
|
843
873
|
}
|
|
844
874
|
return request.questions.map((question) => {
|
|
875
|
+
if (!question.options.length && !question.custom) {
|
|
876
|
+
throw new Error(`Question "${question.key}" has no options and does not accept custom answers`);
|
|
877
|
+
}
|
|
845
878
|
const selected = answers[question.key];
|
|
846
879
|
if (!Array.isArray(selected) || !selected.length || !question.multiple && selected.length !== 1) {
|
|
847
880
|
throw new Error(`Question "${question.key}" requires ${question.multiple ? "at least one answer" : "one answer"}`);
|
package/dist/types.d.ts
CHANGED
|
@@ -309,6 +309,7 @@ export type AgentQuestionOption = {
|
|
|
309
309
|
label: string;
|
|
310
310
|
description: string;
|
|
311
311
|
};
|
|
312
|
+
/** Options are normalised: OpenCode's own type-your-own entry, duplicates and blank labels never appear. */
|
|
312
313
|
export type AgentQuestion = {
|
|
313
314
|
/** Identifies this question in `AgentRunReply.answers`. Unique within a request. */
|
|
314
315
|
key: string;
|
|
@@ -317,7 +318,10 @@ export type AgentQuestion = {
|
|
|
317
318
|
options: AgentQuestionOption[];
|
|
318
319
|
/** More than one option may be selected. */
|
|
319
320
|
multiple: boolean;
|
|
320
|
-
/**
|
|
321
|
+
/**
|
|
322
|
+
* A free-text answer outside `options` is accepted.
|
|
323
|
+
* Defaults to true, matching OpenCode; false only when the agent sets it.
|
|
324
|
+
*/
|
|
321
325
|
custom: boolean;
|
|
322
326
|
};
|
|
323
327
|
/** The agent called OpenCode's `question` tool. Answer every question in one reply. */
|