@yadsh/dsh-qa-surface 0.20.0 → 0.21.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 (60) hide show
  1. package/README.md +54 -0
  2. package/lib/client/QaTranscriptAdapter.js +36 -1
  3. package/lib/client/QaTranscriptAdapter.js.map +1 -1
  4. package/lib/client/chat-artifacts.js +1 -0
  5. package/lib/client/chat-artifacts.js.map +1 -1
  6. package/lib/client/components/QaArtifactAttachment.js +12 -0
  7. package/lib/client/components/QaArtifactAttachment.js.map +1 -0
  8. package/lib/client/components/QaChangelog.js +25 -0
  9. package/lib/client/components/QaChangelog.js.map +1 -1
  10. package/lib/client/components/QaFilesPanel.js +2 -8
  11. package/lib/client/components/QaFilesPanel.js.map +1 -1
  12. package/lib/client/components/QaMessage.js +3 -8
  13. package/lib/client/components/QaMessage.js.map +1 -1
  14. package/lib/client/components/QaWorkGroup.js +1 -3
  15. package/lib/client/components/QaWorkGroup.js.map +1 -1
  16. package/lib/client/settings/card.js +2 -2
  17. package/lib/client/settings/card.js.map +1 -1
  18. package/lib/client/settings/sections/file-writes.js +15 -0
  19. package/lib/client/settings/sections/file-writes.js.map +1 -0
  20. package/lib/client/settings/sections.js +1 -0
  21. package/lib/client/settings/sections.js.map +1 -1
  22. package/lib/client/tool-presentation.js +21 -3
  23. package/lib/client/tool-presentation.js.map +1 -1
  24. package/lib/client.js +8 -8
  25. package/lib/client.js.map +1 -1
  26. package/lib/config-resolvers/defaults.js +2 -0
  27. package/lib/config-resolvers/defaults.js.map +1 -1
  28. package/lib/config-resolvers/tools.js +2 -0
  29. package/lib/config-resolvers/tools.js.map +1 -1
  30. package/lib/config.js +26 -1
  31. package/lib/config.js.map +1 -1
  32. package/lib/index.js +13 -0
  33. package/lib/index.js.map +1 -1
  34. package/lib/prompt-notes.js +6 -2
  35. package/lib/prompt-notes.js.map +1 -1
  36. package/lib/qa-tools/catalog.js +16 -1
  37. package/lib/qa-tools/catalog.js.map +1 -1
  38. package/lib/qa-tools/file-write-gate.js +47 -0
  39. package/lib/qa-tools/file-write-gate.js.map +1 -0
  40. package/lib/qa-tools/index.js +6 -0
  41. package/lib/qa-tools/index.js.map +1 -1
  42. package/lib/qa-tools/subagent-tools.js +159 -0
  43. package/lib/qa-tools/subagent-tools.js.map +1 -0
  44. package/lib/shared/file-write-policy.js +29 -0
  45. package/lib/shared/file-write-policy.js.map +1 -0
  46. package/lib/typert.host.js +124 -116
  47. package/lib/typert.remote-client.js +119 -115
  48. package/lib/types/client/components/QaArtifactAttachment.d.ts +8 -0
  49. package/lib/types/client/settings/sections/file-writes.d.ts +4 -0
  50. package/lib/types/client/settings/sections.d.ts +1 -0
  51. package/lib/types/client/tool-presentation.d.ts +1 -0
  52. package/lib/types/prompt-notes.d.ts +1 -1
  53. package/lib/types/qa-tools/catalog.d.ts +3 -1
  54. package/lib/types/qa-tools/file-write-gate.d.ts +6 -0
  55. package/lib/types/qa-tools/index.d.ts +1 -0
  56. package/lib/types/qa-tools/subagent-tools.d.ts +40 -0
  57. package/lib/types/shared/file-write-policy.d.ts +10 -0
  58. package/lib/types/types/config.d.ts +3 -0
  59. package/lib/types/types/documents.d.ts +2 -0
  60. package/package.json +5 -5
@@ -0,0 +1,159 @@
1
+ import { ReasoningEffortId } from "@deepseek-ai/dsh-llm";
2
+ import { defineTool } from "@deepseek-ai/dsh-tools";
3
+ import { modelPolicySatisfied, projectModelCatalog, } from "../access/model-policy.js";
4
+ import { assertUserModelSelection } from "../access/model-choices.js";
5
+ function caller(agent) {
6
+ if (agent === undefined)
7
+ throw new Error("A QA agent is required.");
8
+ return agent;
9
+ }
10
+ /** Only live catalog entries covered by the owner's current model grants. */
11
+ export function createQaListSubagentModelsTool(options) {
12
+ return defineTool({
13
+ name: "qa_list_subagent_models",
14
+ description: "List the current user's available subagent models and allowed reasoning efforts. Use the returned provider/model ids with qa_subagent. The chat's own model is unchanged. Read this list again after a model refusal; permissions and availability can change.",
15
+ parameters: {},
16
+ output: {
17
+ schema: { type: "string" },
18
+ render: (_args, value) => [{ type: "text", text: value }],
19
+ },
20
+ execute: async (_args, exec) => {
21
+ const agent = caller(exec.agent);
22
+ options.policy(agent);
23
+ exec.signal.throwIfAborted();
24
+ const catalog = projectModelCatalog(await options.ctx.sessionController.modelCatalog());
25
+ const policy = options.policy(agent);
26
+ exec.signal.throwIfAborted();
27
+ const choices = [
28
+ ...(policy.pair === undefined ? [] : [policy.pair]),
29
+ ...(policy.allowedModels ?? []),
30
+ ];
31
+ const models = catalog
32
+ .filter((entry) => choices.some((pair) => pair.provider === entry.provider && pair.model === entry.model))
33
+ .map((entry) => ({
34
+ ...entry,
35
+ reasoningEfforts: entry.reasoningEfforts.filter((reasoningEffort) => modelPolicySatisfied(policy, { ...entry, reasoningEffort })),
36
+ }))
37
+ .filter((entry) => entry.reasoningEfforts.length > 0 ||
38
+ modelPolicySatisfied(policy, entry));
39
+ return JSON.stringify({ models }, null, 2);
40
+ },
41
+ });
42
+ }
43
+ /** Start a fresh native child, with route authority supplied by QA ownership. */
44
+ export function createQaSubagentTool(options) {
45
+ return defineTool({
46
+ name: "qa_subagent",
47
+ description: "Delegate a self-contained task to a fresh subagent on an allowed model. Choose an exact provider/model pair and allowed reasoning_effort from qa_list_subagent_models. Include all necessary context. The child inherits this agent's preset, workspace and permission boundaries. Returns a child id; completion is delivered automatically. Do independent work or end this step without another tool call. Do not poll list_agents, send reminders, or interrupt a child to hurry it. Independent delegations may start together.",
48
+ parameters: {
49
+ description: {
50
+ type: "string",
51
+ required: true,
52
+ description: "Short display name for this task.",
53
+ },
54
+ prompt: {
55
+ type: "string",
56
+ required: true,
57
+ description: "Complete self-contained task for the child.",
58
+ },
59
+ provider: {
60
+ type: "string",
61
+ required: true,
62
+ description: "Exact provider id from qa_list_subagent_models.",
63
+ },
64
+ model: {
65
+ type: "string",
66
+ required: true,
67
+ description: "Exact model id from qa_list_subagent_models.",
68
+ },
69
+ reasoning_effort: {
70
+ type: "string",
71
+ description: "Allowed effort for this model. Omit to use its default effort.",
72
+ },
73
+ },
74
+ output: {
75
+ schema: {
76
+ type: "object",
77
+ additionalProperties: false,
78
+ properties: {
79
+ kind: { type: "string", const: "activation", required: true },
80
+ subagentId: { type: "string", required: true },
81
+ provider: { type: "string", required: true },
82
+ model: { type: "string", required: true },
83
+ reasoningEffort: { type: "string" },
84
+ },
85
+ },
86
+ render: (_args, value) => [{ type: "text", text: JSON.stringify(value) }],
87
+ },
88
+ execute: async (args, exec) => {
89
+ const parent = caller(exec.agent);
90
+ const policy = () => options.policy(parent);
91
+ policy();
92
+ if (args.description.trim() === "" || args.prompt.trim() === "")
93
+ throw new Error("The subagent description and prompt must be non-empty.");
94
+ exec.signal.throwIfAborted();
95
+ const runtime = options.runtime();
96
+ const backend = runtime?.getProvider("spawn");
97
+ if (runtime === undefined ||
98
+ backend === undefined ||
99
+ typeof runtime.resolveMaxDepth !== "function" ||
100
+ typeof runtime.startActivation !== "function")
101
+ throw new Error("The native spawn subagent provider is unavailable.");
102
+ if (!backend.capabilities.agentOptions ||
103
+ !backend.capabilities.depthLimit)
104
+ throw new Error("The spawn provider cannot enforce model selection and delegation depth.");
105
+ const request = {
106
+ provider: args.provider,
107
+ model: args.model,
108
+ ...(args.reasoning_effort === undefined
109
+ ? {}
110
+ : { reasoningEffort: args.reasoning_effort }),
111
+ };
112
+ await assertUserModelSelection(options.ctx, policy, request);
113
+ const selected = await options.ctx.llm.resolveCallConfig({
114
+ provider: request.provider,
115
+ model: request.model,
116
+ ...(request.reasoningEffort === undefined
117
+ ? {}
118
+ : { reasoningEffort: ReasoningEffortId(request.reasoningEffort) }),
119
+ }, exec.signal);
120
+ if (selected.provider !== request.provider ||
121
+ selected.model !== request.model)
122
+ throw new Error("The provider resolved a different model; retry with an available model.");
123
+ // Resolution may await a provider. Recheck grants and catalog before
124
+ // creating anything, including the adapter's default reasoning effort.
125
+ await assertUserModelSelection(options.ctx, policy, selected);
126
+ exec.signal.throwIfAborted();
127
+ // Cordis returns a new tracing proxy for each service read. Compare the
128
+ // registered backend itself, not those context-bound service wrappers.
129
+ if (options.runtime()?.getProvider("spawn") !== backend)
130
+ throw new Error("The spawn provider changed; retry the delegation.");
131
+ const maxDepth = runtime.resolveMaxDepth(undefined);
132
+ const agentOptions = {
133
+ provider: selected.provider,
134
+ model: selected.model,
135
+ ...(selected.reasoningEffort === undefined
136
+ ? {}
137
+ : { reasoningEffort: selected.reasoningEffort }),
138
+ };
139
+ const started = await runtime.startActivation({
140
+ provider: "spawn",
141
+ label: args.description,
142
+ signal: exec.signal,
143
+ delivery: "parent",
144
+ request: {
145
+ parent,
146
+ prompt: [{ type: "text", text: args.prompt }],
147
+ agentOptions,
148
+ ...(maxDepth === undefined ? {} : { maxDepth }),
149
+ },
150
+ });
151
+ return {
152
+ kind: "activation",
153
+ subagentId: started.childId,
154
+ ...agentOptions,
155
+ };
156
+ },
157
+ });
158
+ }
159
+ //# sourceMappingURL=subagent-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-tools.js","sourceRoot":"","sources":["../../src/qa-tools/subagent-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export const QA_FILE_WRITE_EXTENSION_PATTERN = /^\s*\.?[a-z0-9_-]+(?:\.[a-z0-9_-]+)*\s*$/iu;
2
+ export const DEFAULT_QA_FILE_WRITE_POLICY = Object.freeze({
3
+ blockedExtensions: Object.freeze([".py", ".pyw"]),
4
+ message: "Запись файлов этого типа запрещена настройками QA. Не создавайте и не запускайте обходные скрипты. Используйте доступные инструменты для работы с документами и таблицами; если нужной операции нет, сообщите об ограничении.",
5
+ });
6
+ /** Normalize exact suffixes; wildcard and path rules are deliberately unsupported. */
7
+ export function resolveFileWritePolicy(input) {
8
+ const extensions = input?.blockedExtensions ?? DEFAULT_QA_FILE_WRITE_POLICY.blockedExtensions;
9
+ if (!Array.isArray(extensions) || extensions.length > 100)
10
+ throw new Error("tools.fileWritePolicy.blockedExtensions must be an array of at most 100 extensions");
11
+ const normalized = extensions.map((value) => {
12
+ if (typeof value !== "string" ||
13
+ !QA_FILE_WRITE_EXTENSION_PATTERN.test(value) ||
14
+ value.length > 64)
15
+ throw new Error("tools.fileWritePolicy.blockedExtensions must contain extensions such as .py, without paths or wildcards");
16
+ const extension = value.trim().toLowerCase();
17
+ return extension.startsWith(".") ? extension : `.${extension}`;
18
+ });
19
+ const message = input?.message ?? DEFAULT_QA_FILE_WRITE_POLICY.message;
20
+ if (typeof message !== "string" ||
21
+ message.trim() === "" ||
22
+ message.length > 4000)
23
+ throw new Error("tools.fileWritePolicy.message must be non-empty and at most 4000 characters");
24
+ return Object.freeze({
25
+ blockedExtensions: Object.freeze([...new Set(normalized)]),
26
+ message: message.trim(),
27
+ });
28
+ }
29
+ //# sourceMappingURL=file-write-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-write-policy.js","sourceRoot":"","sources":["../../src/shared/file-write-policy.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,+BAA+B,GAC1C,4CAA4C,CAAC;AAE/C,MAAM,CAAC,MAAM,4BAA4B,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC3E,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACjD,OAAO,EACL,+NAA+N;CAClO,CAAC,CAAC;AAEH,sFAAsF;AACtF,MAAM,UAAU,sBAAsB,CACpC,KAAkC;IAElC,MAAM,UAAU,GACd,KAAK,EAAE,iBAAiB,IAAI,4BAA4B,CAAC,iBAAiB,CAAC;IAC7E,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,GAAG;QACvD,MAAM,IAAI,KAAK,CACb,oFAAoF,CACrF,CAAC;IACJ,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,KAAc,EAAE,EAAE;QACnD,IACE,OAAO,KAAK,KAAK,QAAQ;YACzB,CAAC,+BAA+B,CAAC,IAAI,CAAC,KAAK,CAAC;YAC5C,KAAK,CAAC,MAAM,GAAG,EAAE;YAEjB,MAAM,IAAI,KAAK,CACb,yGAAyG,CAC1G,CAAC;QACJ,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC7C,OAAO,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,KAAK,EAAE,OAAO,IAAI,4BAA4B,CAAC,OAAO,CAAC;IACvE,IACE,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE;QACrB,OAAO,CAAC,MAAM,GAAG,IAAI;QAErB,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAC;IACJ,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;QAC1D,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;KACxB,CAAC,CAAC;AACL,CAAC"}