kiokuko-dsh 0.2.28 → 0.2.30
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/dist/dsh/clarification-context.d.ts.map +1 -1
- package/dist/dsh/clarification-context.js +24 -7
- package/dist/dsh/clarification-context.js.map +1 -1
- package/dist/dsh/coding-workflow/host.d.ts +1 -1
- package/dist/dsh/coding-workflow/host.d.ts.map +1 -1
- package/dist/dsh/coding-workflow/host.js +226 -83
- package/dist/dsh/coding-workflow/host.js.map +1 -1
- package/dist/dsh/core/host.d.ts.map +1 -1
- package/dist/dsh/core/host.js +1026 -315
- package/dist/dsh/core/host.js.map +1 -1
- package/dist/dsh/core/tasks.d.ts.map +1 -1
- package/dist/dsh/core/tasks.js +9 -2
- package/dist/dsh/core/tasks.js.map +1 -1
- package/dist/dsh/decisions/intent-assessment.d.ts +1 -0
- package/dist/dsh/decisions/intent-assessment.d.ts.map +1 -1
- package/dist/dsh/decisions/intent-assessment.js +100 -18
- package/dist/dsh/decisions/intent-assessment.js.map +1 -1
- package/dist/dsh/decisions/request-intent.d.ts.map +1 -1
- package/dist/dsh/decisions/request-intent.js +405 -138
- package/dist/dsh/decisions/request-intent.js.map +1 -1
- package/dist/dsh/host-adapter/admission.d.ts +2 -1
- package/dist/dsh/host-adapter/admission.d.ts.map +1 -1
- package/dist/dsh/host-adapter/admission.js +877 -312
- package/dist/dsh/host-adapter/admission.js.map +1 -1
- package/dist/dsh/host-adapter.d.ts.map +1 -1
- package/dist/dsh/host-adapter.js +1 -0
- package/dist/dsh/host-adapter.js.map +1 -1
- package/dist/dsh/on-demand-intake.d.ts +1 -0
- package/dist/dsh/on-demand-intake.d.ts.map +1 -1
- package/dist/dsh/on-demand-intake.js +1120 -316
- package/dist/dsh/on-demand-intake.js.map +1 -1
- package/dist/dsh/request-proposals.d.ts +8 -0
- package/dist/dsh/request-proposals.d.ts.map +1 -0
- package/dist/dsh/request-proposals.js +67 -0
- package/dist/dsh/request-proposals.js.map +1 -0
- package/dist/dsh/skill-prompts.json +1 -1
- package/dist/locale/en.json +1 -1
- package/dist/locale/ja.json +1 -1
- package/dist/locale/ko.json +1 -1
- package/dist/locale/zh-CN.json +1 -1
- package/package.json +2 -2
- package/skills/coding-ideal-routine-skill/SKILL.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clarification-context.d.ts","sourceRoot":"","sources":["../../src/dsh/clarification-context.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;
|
|
1
|
+
{"version":3,"file":"clarification-context.d.ts","sourceRoot":"","sources":["../../src/dsh/clarification-context.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AACD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;CACtC;AACD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAA;IAChD,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAA;CACjD;AACD,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,SAAS,mBAAmB,EAAE,EACxC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,GAC/C,oBAAoB,CAmBtB;AACD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,mBAAmB,GAAG,SAAS,CAYjC;AACD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,oBAAoB,EAC7B,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,GAC5C;IAAE,OAAO,EAAE,oBAAoB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAmBpD"}
|
|
@@ -18,14 +18,31 @@ export function collectClarificationContext(messages, known) {
|
|
|
18
18
|
return { sources: [...sources.values()], answers: [...answers.values()] };
|
|
19
19
|
}
|
|
20
20
|
export function reusableClarificationAnswer(context, question, scope) {
|
|
21
|
-
const answer = context.answers
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
const answer = [...context.answers]
|
|
22
|
+
.reverse()
|
|
23
|
+
.find((answer) => answer.question === question);
|
|
24
|
+
return answer?.question === question &&
|
|
25
|
+
answer.scope === scope &&
|
|
26
|
+
answer.sourceIds.length === context.sources.length &&
|
|
27
|
+
answer.sourceIds.every((id) => context.sources.some((source) => source.id === id))
|
|
28
|
+
? answer
|
|
29
|
+
: undefined;
|
|
24
30
|
}
|
|
25
31
|
export function clarificationReply(context, input) {
|
|
26
|
-
const answer = {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
const answer = {
|
|
33
|
+
...input,
|
|
34
|
+
sourceIds: context.sources.map((source) => source.id),
|
|
35
|
+
};
|
|
36
|
+
const prior = context.answers
|
|
37
|
+
.map((value) => `Earlier native user answer to clarification "${value.question}" (source revision ${value.questionId}:${value.id}):\n${value.value}`)
|
|
38
|
+
.join('\n\n');
|
|
39
|
+
const content = `Original user request (unchanged):\n${context.sources.map((source) => source.text).join('\n')}\n\n${prior ? prior + '\n\n' : ''}Latest native user answer to clarification "${input.question}" (source revision ${input.questionId}:${input.id}; same question and current scope):\n${input.value}\n\nInterpret this latest explicit answer as a revision only where it changes the earlier instruction within this question’s scope. Preserve unrelated constraints. Native permissions and task ownership still apply.`;
|
|
40
|
+
return {
|
|
41
|
+
context: {
|
|
42
|
+
sources: [...context.sources],
|
|
43
|
+
answers: [...context.answers, answer],
|
|
44
|
+
},
|
|
45
|
+
content,
|
|
46
|
+
};
|
|
30
47
|
}
|
|
31
48
|
//# sourceMappingURL=clarification-context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clarification-context.js","sourceRoot":"","sources":["../../src/dsh/clarification-context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"clarification-context.js","sourceRoot":"","sources":["../../src/dsh/clarification-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,7 +30,7 @@ export interface CodingHost {
|
|
|
30
30
|
/** Only definitions produced by this plugin may join an already active Lisp fence. */
|
|
31
31
|
export declare function isCodingWorkflowTool(definition: unknown): boolean;
|
|
32
32
|
export declare function isCodingWorkflowStatus(definition: unknown, args: unknown): boolean;
|
|
33
|
-
export declare const CODING_GUIDANCE = "
|
|
33
|
+
export declare const CODING_GUIDANCE = "An observational coding_workflow status may return applicable:false when no native task is enrolled; this is not an execution error or a requirement to enroll ordinary conversation. For an explicitly prepared coding task, use coding_workflow status/next to inspect the current revision and pending action. Submit new or revised Goals with coding_workflow_apply (action propose/revise, expectedRevision, definition); register blockers with coding_workflow_blocker. Legacy coding_workflow propose/revise/report_blocker calls remain accepted for compatibility. Preserve the exact request interpretation and evidence references shown by the host. A pending scope change requires a revised Goal before implementation; a same-scope continuation keeps its existing Goal, Lisp choice, and unfinished items. The host shows the Goal/items/criteria and asks once whether to use Lisp for this task. Pending choice blocks implementation, not conversation or reads. Bind checks with task_completion before executing them. Use host-observed selected tests, output/artifact assertions or browser assertions; exit 0 and model claims alone cannot complete this workflow. Fix failures autonomously within existing permissions. Final Goal verification must run after item checks on the current artifact. Report the Goal, evidence, ordinary-use result and remaining blockers.";
|
|
34
34
|
export declare function codingChoiceDetail(value: CodingWorkflow): string;
|
|
35
35
|
export declare const parseCodingChoice: typeof parseLispCodingChoice;
|
|
36
36
|
/** The same host seam is mounted by the suite and by the independent core. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../../src/dsh/coding-workflow/host.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../../src/dsh/coding-workflow/host.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAEL,qBAAqB,EACtB,MAAM,uBAAuB,CAAA;AAI9B,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAA;AAQvB,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,gCAAgC,CAAA;AAgBvC,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,GAAG,CAAA;IACX,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,WAAW,CAAA;CACpB;AACD,UAAU,YAAa,SAAQ,cAAc;IAC3C,KAAK,EAAE,GAAG,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,aAAa,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAA;IACjD,oBAAoB,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAA;CACxD;AACD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,cAAc,CAAA;IACvB,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,CAAA;IACvD,SAAS,CAAC,EAAE,gBAAgB,CAAA;IAC5B,IAAI,IAAI,iBAAiB,GAAG,SAAS,CAAA;IACrC,eAAe,CAAC,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAA;IAC/C,aAAa,CAAC,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAA;IAC7C,UAAU,CAAC,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAA;CAC3C;AA6FD,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAMjE;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,OAAO,GACZ,OAAO,CAMT;AAED,eAAO,MAAM,eAAe,+0CACkzC,CAAA;AAE90C,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAgBhE;AACD,eAAO,MAAM,iBAAiB,8BAAwB,CAAA;AAEtD,8EAA8E;AAC9E,wBAAgB,mBAAmB,CACjC,GAAG,EAAE;IACH,KAAK,EAAE;QACL,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,IAAI,CAAA;QAC/B,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,GAAG,GAAG,CAAA;KACrC,CAAA;IACD,EAAE,CACA,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,EACrC,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,GAC7B,MAAM,IAAI,CAAA;CACd,EACD,IAAI,EAAE,UAAU,GACf,MAAM,IAAI,CAydZ"}
|
|
@@ -1,22 +1,47 @@
|
|
|
1
1
|
import * as z from 'zod/v4';
|
|
2
|
-
import { askLispCodingQuestion, parseLispCodingChoice } from '../coding-question.js';
|
|
2
|
+
import { askLispCodingQuestion, parseLispCodingChoice, } from '../coding-question.js';
|
|
3
3
|
import { KiokukoError } from '../../errors.js';
|
|
4
4
|
import { foregroundNativeCommand } from '../memory-application.js';
|
|
5
5
|
import { canonicalContentHash } from '../../serialization/validate.js';
|
|
6
|
-
import { CodingBlockerSchema, CodingDefinitionSchema } from './contracts.js';
|
|
7
|
-
import { codingControlOrRead, codingControlCarrier, codingLiteralCarrier, executionRequestAction, CODING_READ_ONLY } from './intent.js';
|
|
6
|
+
import { CodingBlockerSchema, CodingDefinitionSchema, } from './contracts.js';
|
|
7
|
+
import { codingControlOrRead, codingControlCarrier, codingLiteralCarrier, executionRequestAction, CODING_READ_ONLY, } from './intent.js';
|
|
8
8
|
import { readCodingWorkflow } from './store.js';
|
|
9
|
-
import { answerCodingChoice, beginCodingDispatch, nextCodingWork, proposeCodingWorkflow, reportCodingBlocker, synchronizeCodingWorkflow, clearCodingRuntimeBlocker, assertCodingCommandRetry, projectEnnoCodingWorkflow, onCodingInterrupted } from './service.js';
|
|
9
|
+
import { answerCodingChoice, beginCodingDispatch, nextCodingWork, proposeCodingWorkflow, reportCodingBlocker, synchronizeCodingWorkflow, clearCodingRuntimeBlocker, assertCodingCommandRetry, projectEnnoCodingWorkflow, onCodingInterrupted, } from './service.js';
|
|
10
10
|
const statusSchema = z.object({ action: z.literal('status') }).strict();
|
|
11
11
|
const nextSchema = z.object({ action: z.literal('next') }).strict();
|
|
12
|
-
const applySchema = z
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const applySchema = z
|
|
13
|
+
.object({
|
|
14
|
+
action: z.enum(['propose', 'revise']),
|
|
15
|
+
expectedRevision: z.number().int().min(1),
|
|
16
|
+
definition: CodingDefinitionSchema,
|
|
17
|
+
})
|
|
18
|
+
.strict();
|
|
19
|
+
const blockerSchema = z
|
|
20
|
+
.object({
|
|
21
|
+
expectedRevision: z.number().int().min(1),
|
|
22
|
+
blocker: CodingBlockerSchema,
|
|
23
|
+
})
|
|
24
|
+
.strict();
|
|
25
|
+
const legacyBlockerSchema = z
|
|
26
|
+
.object({
|
|
27
|
+
action: z.literal('report_blocker'),
|
|
28
|
+
expectedRevision: z.number().int().min(1),
|
|
29
|
+
blocker: CodingBlockerSchema,
|
|
30
|
+
})
|
|
31
|
+
.strict();
|
|
32
|
+
const legacySchema = z.discriminatedUnion('action', [
|
|
33
|
+
statusSchema,
|
|
34
|
+
nextSchema,
|
|
35
|
+
applySchema,
|
|
36
|
+
legacyBlockerSchema,
|
|
37
|
+
]);
|
|
16
38
|
function jsonSchema(schema) {
|
|
17
39
|
return JSON.parse(JSON.stringify(z.toJSONSchema(schema)));
|
|
18
40
|
}
|
|
19
|
-
const legacyParameters = {
|
|
41
|
+
const legacyParameters = {
|
|
42
|
+
type: 'object',
|
|
43
|
+
oneOf: [statusSchema, nextSchema, applySchema, legacyBlockerSchema].map(jsonSchema),
|
|
44
|
+
};
|
|
20
45
|
function validationCorrection(field) {
|
|
21
46
|
if (field === 'expectedRevision')
|
|
22
47
|
return 'Use the current revision returned by coding_workflow status.';
|
|
@@ -32,31 +57,55 @@ function parseInput(schema, raw, toolName) {
|
|
|
32
57
|
const parsed = schema.safeParse(raw);
|
|
33
58
|
if (parsed.success)
|
|
34
59
|
return parsed.data;
|
|
35
|
-
const issues = parsed.error.issues.map(issue => {
|
|
60
|
+
const issues = parsed.error.issues.map((issue) => {
|
|
36
61
|
const field = issue.path.map(String).join('.') || 'input';
|
|
37
|
-
return {
|
|
62
|
+
return {
|
|
63
|
+
field,
|
|
64
|
+
reason: issue.message.slice(0, 240),
|
|
65
|
+
correction: issue.message.startsWith('Duplicate IDs:')
|
|
66
|
+
? 'Use unique goalId/itemId/criterionId declaration values; keep reference arrays pointing to the intended declarations.'
|
|
67
|
+
: issue.message.includes('Goal criterion has no implementing item')
|
|
68
|
+
? 'Preserve the final Goal check. Add its named ID to the responsible definition.items[].goalCriterionIds; do not invent which item implements it.'
|
|
69
|
+
: issue.message.includes('Unknown Goal criterion')
|
|
70
|
+
? 'Use a declared definition.goal.criterionIds value in this item reference.'
|
|
71
|
+
: validationCorrection(field),
|
|
72
|
+
};
|
|
38
73
|
});
|
|
39
|
-
const summary = issues
|
|
74
|
+
const summary = issues
|
|
75
|
+
.map((issue) => `${issue.field}: ${issue.reason}. Correction: ${issue.correction}`)
|
|
76
|
+
.join('\n');
|
|
40
77
|
throw new KiokukoError('VALIDATION_ERROR', `Invalid ${toolName} input.\n${summary}`, { issues });
|
|
41
78
|
}
|
|
42
79
|
const codingToolDefinitions = new WeakSet();
|
|
43
|
-
function codingTool(definition) {
|
|
80
|
+
function codingTool(definition) {
|
|
81
|
+
codingToolDefinitions.add(definition.execute);
|
|
82
|
+
return definition;
|
|
83
|
+
}
|
|
44
84
|
/** Only definitions produced by this plugin may join an already active Lisp fence. */
|
|
45
85
|
export function isCodingWorkflowTool(definition) {
|
|
46
|
-
return typeof definition === 'object' &&
|
|
86
|
+
return (typeof definition === 'object' &&
|
|
87
|
+
definition !== null &&
|
|
88
|
+
codingToolDefinitions.has(definition.execute));
|
|
47
89
|
}
|
|
48
90
|
export function isCodingWorkflowStatus(definition, args) {
|
|
49
|
-
return isCodingWorkflowTool(definition) &&
|
|
50
|
-
&&
|
|
91
|
+
return (isCodingWorkflowTool(definition) &&
|
|
92
|
+
definition.name === 'coding_workflow' &&
|
|
93
|
+
statusSchema.safeParse(args).success);
|
|
51
94
|
}
|
|
52
|
-
export const CODING_GUIDANCE = '
|
|
95
|
+
export const CODING_GUIDANCE = 'An observational coding_workflow status may return applicable:false when no native task is enrolled; this is not an execution error or a requirement to enroll ordinary conversation. For an explicitly prepared coding task, use coding_workflow status/next to inspect the current revision and pending action. Submit new or revised Goals with coding_workflow_apply (action propose/revise, expectedRevision, definition); register blockers with coding_workflow_blocker. Legacy coding_workflow propose/revise/report_blocker calls remain accepted for compatibility. Preserve the exact request interpretation and evidence references shown by the host. A pending scope change requires a revised Goal before implementation; a same-scope continuation keeps its existing Goal, Lisp choice, and unfinished items. The host shows the Goal/items/criteria and asks once whether to use Lisp for this task. Pending choice blocks implementation, not conversation or reads. Bind checks with task_completion before executing them. Use host-observed selected tests, output/artifact assertions or browser assertions; exit 0 and model claims alone cannot complete this workflow. Fix failures autonomously within existing permissions. Final Goal verification must run after item checks on the current artifact. Report the Goal, evidence, ordinary-use result and remaining blockers.';
|
|
53
96
|
export function codingChoiceDetail(value) {
|
|
54
97
|
const definition = value.definition;
|
|
55
|
-
const criterion = (id) => {
|
|
56
|
-
|
|
57
|
-
|
|
98
|
+
const criterion = (id) => {
|
|
99
|
+
const item = definition.criteria.find((item) => item.criterionId === id);
|
|
100
|
+
return `${item.outcome} / 確認: ${item.procedure} / 期待: ${item.expected}`;
|
|
101
|
+
};
|
|
102
|
+
return [
|
|
103
|
+
`Goal: ${definition.goal.ideal}`,
|
|
104
|
+
`対象: ${definition.goal.target}`,
|
|
105
|
+
...definition.items.map((item) => `- ${item.change}\n${item.criterionIds.map((id) => ` ${criterion(id)}`).join('\n')}`),
|
|
58
106
|
`最終確認: ${definition.goal.criterionIds.map(criterion).join('\n')}`,
|
|
59
|
-
'選択はこのタスクだけに適用します。未回答では実装を開始しません。取消・Skip は作業を保持してこの試行を中止します。カードの非表示だけでは質問は終了しません。Lisp は通常の開発環境で動き、既存の権限と承認は引き続き適用されます。'
|
|
107
|
+
'選択はこのタスクだけに適用します。未回答では実装を開始しません。取消・Skip は作業を保持してこの試行を中止します。カードの非表示だけでは質問は終了しません。Lisp は通常の開発環境で動き、既存の権限と承認は引き続き適用されます。',
|
|
108
|
+
].join('\n\n');
|
|
60
109
|
}
|
|
61
110
|
export const parseCodingChoice = parseLispCodingChoice;
|
|
62
111
|
/** The same host seam is mounted by the suite and by the independent core. */
|
|
@@ -66,16 +115,22 @@ export function mountCodingWorkflow(ctx, host) {
|
|
|
66
115
|
const scopes = new WeakMap();
|
|
67
116
|
const current = (identity, execution) => {
|
|
68
117
|
const resolved = host.resolve(execution);
|
|
69
|
-
if (!resolved ||
|
|
118
|
+
if (!resolved ||
|
|
119
|
+
resolved.runId !== identity.runId ||
|
|
120
|
+
resolved.sessionId !== identity.sessionId ||
|
|
121
|
+
resolved.agent !== identity.agent)
|
|
70
122
|
throw new KiokukoError('CONFLICT', 'Coding task changed while awaiting an answer');
|
|
71
123
|
};
|
|
72
124
|
const choose = async (identity, execution) => {
|
|
73
|
-
await host.runtime.withDatabase(db => projectEnnoCodingWorkflow(db, identity));
|
|
74
|
-
const value = await host.runtime.withDatabase(db => readCodingWorkflow(db, identity.runId));
|
|
75
|
-
if (!value?.definition ||
|
|
125
|
+
await host.runtime.withDatabase((db) => projectEnnoCodingWorkflow(db, identity));
|
|
126
|
+
const value = await host.runtime.withDatabase((db) => readCodingWorkflow(db, identity.runId));
|
|
127
|
+
if (!value?.definition ||
|
|
128
|
+
['cancelled', 'superseded', 'completed'].includes(value.state))
|
|
76
129
|
return;
|
|
77
130
|
if (value.choice.state === 'yes' || value.choice.state === 'no')
|
|
78
|
-
host
|
|
131
|
+
host
|
|
132
|
+
.lisp()
|
|
133
|
+
?.answered?.(identity.agent, value.request, value.choice.state, value.choice.answerRef ?? `stored-choice:${value.choice.questionId}`);
|
|
79
134
|
if (value.choice.state !== 'pending') {
|
|
80
135
|
if (value.choice.state === 'yes') {
|
|
81
136
|
try {
|
|
@@ -83,13 +138,18 @@ export function mountCodingWorkflow(ctx, host) {
|
|
|
83
138
|
if (!lisp?.activate)
|
|
84
139
|
throw new Error('Selected Lisp runtime is unavailable');
|
|
85
140
|
await lisp.activate(identity.agent);
|
|
86
|
-
await host.runtime.withDatabase(db => clearCodingRuntimeBlocker(db, identity));
|
|
141
|
+
await host.runtime.withDatabase((db) => clearCodingRuntimeBlocker(db, identity));
|
|
87
142
|
}
|
|
88
143
|
catch (error) {
|
|
89
|
-
const latest = await host.runtime.withDatabase(db => readCodingWorkflow(db, identity.runId));
|
|
144
|
+
const latest = await host.runtime.withDatabase((db) => readCodingWorkflow(db, identity.runId));
|
|
90
145
|
if (latest?.scopeVersion === value.scopeVersion)
|
|
91
|
-
await host.runtime.withDatabase(db => reportCodingBlocker(db, identity, `startup-retry:${latest.revision}`, latest.revision, {
|
|
92
|
-
criterionIds: [],
|
|
146
|
+
await host.runtime.withDatabase((db) => reportCodingBlocker(db, identity, `startup-retry:${latest.revision}`, latest.revision, {
|
|
147
|
+
criterionIds: [],
|
|
148
|
+
kind: 'runtime',
|
|
149
|
+
cause: String(error),
|
|
150
|
+
required: 'Restore Lisp or explicitly change this task’s route',
|
|
151
|
+
recovery: [],
|
|
152
|
+
resumeWhen: 'Lisp startup succeeds',
|
|
93
153
|
}));
|
|
94
154
|
}
|
|
95
155
|
}
|
|
@@ -101,10 +161,14 @@ export function mountCodingWorkflow(ctx, host) {
|
|
|
101
161
|
// Reuse only this task's answer or an explicit manual session preference.
|
|
102
162
|
// A runtime left enabled by another task is not a human answer for this Goal.
|
|
103
163
|
const explicit = lisp?.choiceFor?.(identity.agent, value.request);
|
|
104
|
-
const manual = !explicit && await lisp?.manualSelected?.(identity.agent) === true;
|
|
105
|
-
const early = explicit ??
|
|
106
|
-
|
|
107
|
-
|
|
164
|
+
const manual = !explicit && (await lisp?.manualSelected?.(identity.agent)) === true;
|
|
165
|
+
const early = explicit ??
|
|
166
|
+
(manual
|
|
167
|
+
? {
|
|
168
|
+
choice: 'yes',
|
|
169
|
+
answerRef: `manual-session:${identity.sessionId}:${value.workflowId}:${value.scopeVersion}`,
|
|
170
|
+
}
|
|
171
|
+
: undefined);
|
|
108
172
|
execution.signal.throwIfAborted();
|
|
109
173
|
current(identity, execution);
|
|
110
174
|
if (!host.questions && !early)
|
|
@@ -114,10 +178,21 @@ export function mountCodingWorkflow(ctx, host) {
|
|
|
114
178
|
if (existing)
|
|
115
179
|
return existing;
|
|
116
180
|
const operation = (async () => {
|
|
117
|
-
const result = early
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
181
|
+
const result = early
|
|
182
|
+
? { status: 'answered', ...early }
|
|
183
|
+
: await askLispCodingQuestion(host.questions, {
|
|
184
|
+
agent: identity.agent,
|
|
185
|
+
signal: execution.signal,
|
|
186
|
+
questions: [
|
|
187
|
+
{
|
|
188
|
+
id: value.choice.questionId,
|
|
189
|
+
header: 'Goal と実装項目',
|
|
190
|
+
question: 'このタスクで Lisp モードを使いますか?',
|
|
191
|
+
detail: codingChoiceDetail(value),
|
|
192
|
+
options: ['使う', '使わない', '取消・作業を保持'].map((label) => ({ label })),
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
});
|
|
121
196
|
execution.signal.throwIfAborted();
|
|
122
197
|
current(identity, execution);
|
|
123
198
|
if (result.status === 'pending')
|
|
@@ -126,18 +201,28 @@ export function mountCodingWorkflow(ctx, host) {
|
|
|
126
201
|
throw new KiokukoError('CONFLICT', `Lisp question unavailable: ${result.reason}`);
|
|
127
202
|
const choice = result.status === 'cancelled' ? 'cancelled' : result.choice;
|
|
128
203
|
const answer = { questionId: value.choice.questionId, choice };
|
|
129
|
-
const saved = await host.runtime.withDatabase(db => answerCodingChoice(db, identity, {
|
|
130
|
-
callId: `human:${value.choice.questionId}:${canonicalContentHash(answer)}`,
|
|
131
|
-
|
|
132
|
-
|
|
204
|
+
const saved = await host.runtime.withDatabase((db) => answerCodingChoice(db, identity, {
|
|
205
|
+
callId: `human:${value.choice.questionId}:${canonicalContentHash(answer)}`,
|
|
206
|
+
expectedRevision: value.revision,
|
|
207
|
+
workflowId: value.workflowId,
|
|
208
|
+
scopeVersion: value.scopeVersion,
|
|
209
|
+
questionId: value.choice.questionId,
|
|
210
|
+
questionRevision: value.choice.revision,
|
|
211
|
+
answerRef: early?.answerRef ??
|
|
212
|
+
`userQuestions:${value.choice.questionId}:${canonicalContentHash(answer)}`,
|
|
213
|
+
choice,
|
|
133
214
|
}));
|
|
134
215
|
current(identity, execution);
|
|
135
216
|
if (choice === 'cancelled') {
|
|
136
217
|
host.lisp()?.cancelled?.(identity.agent, value.request);
|
|
137
|
-
controllers
|
|
218
|
+
controllers
|
|
219
|
+
.get(identity.runId)
|
|
220
|
+
?.controller.abort(new Error('Coding task cancelled'));
|
|
138
221
|
return;
|
|
139
222
|
}
|
|
140
|
-
host
|
|
223
|
+
host
|
|
224
|
+
.lisp()
|
|
225
|
+
?.answered?.(identity.agent, value.request, choice, saved.choice.answerRef);
|
|
141
226
|
if (choice === 'no') {
|
|
142
227
|
await host.lisp()?.exclude?.(identity.agent);
|
|
143
228
|
return;
|
|
@@ -147,14 +232,19 @@ export function mountCodingWorkflow(ctx, host) {
|
|
|
147
232
|
if (!lisp?.activate)
|
|
148
233
|
throw new Error('Lisp runtime is unavailable. Keep this task pending recovery or explicitly select another route.');
|
|
149
234
|
await lisp.activate(identity.agent);
|
|
150
|
-
await host.runtime.withDatabase(db => clearCodingRuntimeBlocker(db, identity));
|
|
235
|
+
await host.runtime.withDatabase((db) => clearCodingRuntimeBlocker(db, identity));
|
|
151
236
|
}
|
|
152
237
|
catch (error) {
|
|
153
|
-
const latest = await host.runtime.withDatabase(db => readCodingWorkflow(db, identity.runId));
|
|
154
|
-
if (latest?.scopeVersion === saved.scopeVersion &&
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
238
|
+
const latest = await host.runtime.withDatabase((db) => readCodingWorkflow(db, identity.runId));
|
|
239
|
+
if (latest?.scopeVersion === saved.scopeVersion &&
|
|
240
|
+
latest.choice.state === 'yes')
|
|
241
|
+
await host.runtime.withDatabase((db) => reportCodingBlocker(db, identity, `startup:${latest.revision}`, latest.revision, {
|
|
242
|
+
criterionIds: [],
|
|
243
|
+
kind: 'runtime',
|
|
244
|
+
cause: error instanceof Error ? error.message : String(error),
|
|
245
|
+
required: 'Restore the selected Lisp runtime or explicitly change this task’s execution route',
|
|
246
|
+
recovery: [],
|
|
247
|
+
resumeWhen: 'Lisp startup succeeds',
|
|
158
248
|
}));
|
|
159
249
|
}
|
|
160
250
|
})();
|
|
@@ -168,42 +258,63 @@ export function mountCodingWorkflow(ctx, host) {
|
|
|
168
258
|
}
|
|
169
259
|
};
|
|
170
260
|
const definitions = [];
|
|
171
|
-
definitions.push(onCodingInterrupted(runId => controllers
|
|
261
|
+
definitions.push(onCodingInterrupted((runId) => controllers
|
|
262
|
+
.get(runId)
|
|
263
|
+
?.controller.abort(new Error('Coding task stopped'))));
|
|
172
264
|
const executeAction = async (input, identity, execution) => {
|
|
173
265
|
execution.signal.throwIfAborted();
|
|
174
266
|
if (input.action === 'status') {
|
|
175
267
|
current(identity, execution);
|
|
176
|
-
return host.runtime.withDatabase(db => nextCodingWork(db, identity, { readOnly: true }));
|
|
268
|
+
return host.runtime.withDatabase((db) => nextCodingWork(db, identity, { readOnly: true }));
|
|
177
269
|
}
|
|
178
270
|
if (input.action === 'propose' || input.action === 'revise') {
|
|
179
|
-
const before = await host.runtime.withDatabase(db => readCodingWorkflow(db, identity.runId));
|
|
180
|
-
const updated = await host.runtime.withDatabase(db => proposeCodingWorkflow(db, identity, execution.callId, input.expectedRevision, input.definition, input.action === 'revise'));
|
|
271
|
+
const before = await host.runtime.withDatabase((db) => readCodingWorkflow(db, identity.runId));
|
|
272
|
+
const updated = await host.runtime.withDatabase((db) => proposeCodingWorkflow(db, identity, execution.callId, input.expectedRevision, input.definition, input.action === 'revise'));
|
|
181
273
|
if (before?.scopeVersion !== updated.scopeVersion)
|
|
182
|
-
controllers
|
|
274
|
+
controllers
|
|
275
|
+
.get(identity.runId)
|
|
276
|
+
?.controller.abort(new Error('Coding scope changed'));
|
|
183
277
|
await choose(identity, execution);
|
|
184
278
|
}
|
|
185
279
|
else if (input.action === 'report_blocker') {
|
|
186
|
-
await host.runtime.withDatabase(db => reportCodingBlocker(db, identity, execution.callId, input.expectedRevision, input.blocker));
|
|
280
|
+
await host.runtime.withDatabase((db) => reportCodingBlocker(db, identity, execution.callId, input.expectedRevision, input.blocker));
|
|
187
281
|
}
|
|
188
282
|
else if (input.action === 'next')
|
|
189
283
|
await choose(identity, execution);
|
|
190
284
|
current(identity, execution);
|
|
191
|
-
return host.runtime.withDatabase(db => {
|
|
285
|
+
return host.runtime.withDatabase((db) => {
|
|
286
|
+
synchronizeCodingWorkflow(db, identity.runId);
|
|
287
|
+
return nextCodingWork(db, identity);
|
|
288
|
+
});
|
|
192
289
|
};
|
|
193
290
|
const tool = (name, schema, parameters, normalize) => codingTool({
|
|
194
|
-
name,
|
|
195
|
-
|
|
291
|
+
name,
|
|
292
|
+
modelFacing: true,
|
|
293
|
+
description: CODING_GUIDANCE,
|
|
294
|
+
parameters,
|
|
295
|
+
output: {
|
|
296
|
+
schema: {},
|
|
297
|
+
render: (_, result) => [
|
|
298
|
+
{ type: 'text', text: JSON.stringify(result) },
|
|
299
|
+
],
|
|
300
|
+
},
|
|
196
301
|
execute: async (raw, execution) => {
|
|
197
302
|
const identity = host.resolve(execution);
|
|
303
|
+
const input = normalize(parseInput(schema, raw, name));
|
|
304
|
+
if (!identity && execution.name === name && input.action === 'status')
|
|
305
|
+
return {
|
|
306
|
+
applicable: false,
|
|
307
|
+
reason: 'no_active_native_task',
|
|
308
|
+
nextAction: 'Continue ordinary native work. Use an explicitly prepared coding workflow only when the current request calls for it.',
|
|
309
|
+
};
|
|
198
310
|
if (!identity || execution.name !== name)
|
|
199
311
|
throw new KiokukoError('CONFLICT', 'Coding workflow requires this active native task');
|
|
200
|
-
const input = normalize(parseInput(schema, raw, name));
|
|
201
312
|
return executeAction(input, identity, execution);
|
|
202
313
|
},
|
|
203
314
|
});
|
|
204
|
-
definitions.push(ctx.tools.register(tool('coding_workflow', legacySchema, legacyParameters, input => input)));
|
|
205
|
-
definitions.push(ctx.tools.register(tool('coding_workflow_apply', applySchema, jsonSchema(applySchema), input => input)));
|
|
206
|
-
definitions.push(ctx.tools.register(tool('coding_workflow_blocker', blockerSchema, jsonSchema(blockerSchema), input => ({ action: 'report_blocker', ...input }))));
|
|
315
|
+
definitions.push(ctx.tools.register(tool('coding_workflow', legacySchema, legacyParameters, (input) => input)));
|
|
316
|
+
definitions.push(ctx.tools.register(tool('coding_workflow_apply', applySchema, jsonSchema(applySchema), (input) => input)));
|
|
317
|
+
definitions.push(ctx.tools.register(tool('coding_workflow_blocker', blockerSchema, jsonSchema(blockerSchema), (input) => ({ action: 'report_blocker', ...input }))));
|
|
207
318
|
definitions.push(ctx.on('tools/pre-execute', async (execution, next) => {
|
|
208
319
|
if (host.nativeCommand?.(execution) || host.nativeLisp?.(execution))
|
|
209
320
|
return next();
|
|
@@ -211,41 +322,67 @@ export function mountCodingWorkflow(ctx, host) {
|
|
|
211
322
|
if (!identity || host.preparationOnly?.(execution))
|
|
212
323
|
return next();
|
|
213
324
|
const carrier = codingLiteralCarrier(execution.name, execution.arguments);
|
|
214
|
-
if (codingControlOrRead(execution.name) ||
|
|
215
|
-
|
|
216
|
-
|
|
325
|
+
if (codingControlOrRead(execution.name) ||
|
|
326
|
+
codingControlCarrier(execution.name, execution.arguments) ||
|
|
327
|
+
(carrier &&
|
|
328
|
+
ctx.tools.get?.(carrier, identity.agent)?.[CODING_READ_ONLY] ===
|
|
329
|
+
true) ||
|
|
330
|
+
ctx.tools.get?.(execution.name, identity.agent)?.[CODING_READ_ONLY] === true)
|
|
217
331
|
return next();
|
|
218
|
-
const workflow = await host.runtime.withDatabase(db => readCodingWorkflow(db, identity.runId));
|
|
332
|
+
const workflow = await host.runtime.withDatabase((db) => readCodingWorkflow(db, identity.runId));
|
|
219
333
|
try {
|
|
220
334
|
const action = executionRequestAction(identity.requestIntent, identity.requestIntentContext, carrier ?? execution.name);
|
|
221
335
|
if (action === 'verify') {
|
|
222
336
|
if (workflow?.pendingScopeChange)
|
|
223
|
-
return {
|
|
337
|
+
return {
|
|
338
|
+
kind: 'deny',
|
|
339
|
+
reason: 'Revise the pending Goal scope before execution.',
|
|
340
|
+
};
|
|
224
341
|
return next(); // Verification is authorized by the request and still goes through native permissions.
|
|
225
342
|
}
|
|
226
343
|
}
|
|
227
344
|
catch (error) {
|
|
228
|
-
return {
|
|
345
|
+
return {
|
|
346
|
+
kind: 'deny',
|
|
347
|
+
reason: error instanceof Error
|
|
348
|
+
? error.message
|
|
349
|
+
: 'Request interpretation is not current',
|
|
350
|
+
};
|
|
229
351
|
}
|
|
230
352
|
if (!workflow)
|
|
231
353
|
return next();
|
|
232
354
|
try {
|
|
233
|
-
const value = await host.runtime.withDatabase(db => beginCodingDispatch(db, identity, execution.callId, execution.name));
|
|
355
|
+
const value = await host.runtime.withDatabase((db) => beginCodingDispatch(db, identity, execution.callId, execution.name));
|
|
234
356
|
if (value) {
|
|
235
357
|
const command = foregroundNativeCommand(execution, identity.repositoryRoot);
|
|
236
358
|
if (command)
|
|
237
|
-
await host.runtime.withDatabase(db => assertCodingCommandRetry(db, identity, command));
|
|
238
|
-
scopes.set(execution, {
|
|
359
|
+
await host.runtime.withDatabase((db) => assertCodingCommandRetry(db, identity, command));
|
|
360
|
+
scopes.set(execution, {
|
|
361
|
+
scopeVersion: value.scopeVersion,
|
|
362
|
+
identity,
|
|
363
|
+
execute: ctx.tools.get?.(execution.name, identity.agent)?.execute,
|
|
364
|
+
});
|
|
239
365
|
let active = controllers.get(identity.runId);
|
|
240
|
-
if (!active ||
|
|
241
|
-
active
|
|
366
|
+
if (!active ||
|
|
367
|
+
active.scope !== value.scopeVersion ||
|
|
368
|
+
active.controller.signal.aborted) {
|
|
369
|
+
active = {
|
|
370
|
+
scope: value.scopeVersion,
|
|
371
|
+
controller: new AbortController(),
|
|
372
|
+
};
|
|
242
373
|
controllers.set(identity.runId, active);
|
|
243
374
|
}
|
|
244
|
-
execution.signal = AbortSignal.any([
|
|
375
|
+
execution.signal = AbortSignal.any([
|
|
376
|
+
execution.signal,
|
|
377
|
+
active.controller.signal,
|
|
378
|
+
]);
|
|
245
379
|
}
|
|
246
380
|
}
|
|
247
381
|
catch (error) {
|
|
248
|
-
return {
|
|
382
|
+
return {
|
|
383
|
+
kind: 'deny',
|
|
384
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
385
|
+
};
|
|
249
386
|
}
|
|
250
387
|
return next();
|
|
251
388
|
}, { prepend: true }));
|
|
@@ -253,9 +390,12 @@ export function mountCodingWorkflow(ctx, host) {
|
|
|
253
390
|
const scope = scopes.get(execution);
|
|
254
391
|
if (scope) {
|
|
255
392
|
current(scope.identity, execution);
|
|
256
|
-
const value = await host.runtime.withDatabase(db => readCodingWorkflow(db, scope.identity.runId));
|
|
257
|
-
if (!value ||
|
|
258
|
-
|
|
393
|
+
const value = await host.runtime.withDatabase((db) => readCodingWorkflow(db, scope.identity.runId));
|
|
394
|
+
if (!value ||
|
|
395
|
+
value.scopeVersion !== scope.scopeVersion ||
|
|
396
|
+
['cancelled', 'superseded'].includes(value.state) ||
|
|
397
|
+
ctx.tools.get?.(execution.name, scope.identity.agent)?.execute !==
|
|
398
|
+
scope.execute)
|
|
259
399
|
throw new KiokukoError('CONFLICT', 'Coding dispatch changed during native approval');
|
|
260
400
|
execution.signal.throwIfAborted();
|
|
261
401
|
}
|
|
@@ -268,11 +408,14 @@ export function mountCodingWorkflow(ctx, host) {
|
|
|
268
408
|
if (identity) {
|
|
269
409
|
if (['enno_plan_submit', 'enno_plan_review'].includes(execution.name))
|
|
270
410
|
await choose(identity, execution);
|
|
271
|
-
await host.runtime.withDatabase(db => synchronizeCodingWorkflow(db, identity.runId));
|
|
411
|
+
await host.runtime.withDatabase((db) => synchronizeCodingWorkflow(db, identity.runId));
|
|
272
412
|
}
|
|
273
413
|
}));
|
|
274
|
-
return () => {
|
|
275
|
-
|
|
276
|
-
|
|
414
|
+
return () => {
|
|
415
|
+
for (const active of controllers.values())
|
|
416
|
+
active.controller.abort(new Error('Coding host stopped'));
|
|
417
|
+
for (const dispose of definitions.reverse())
|
|
418
|
+
dispose();
|
|
419
|
+
};
|
|
277
420
|
}
|
|
278
421
|
//# sourceMappingURL=host.js.map
|