@alex.botez/clarifying-ideas 1.0.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/LICENSE +21 -0
- package/README.md +96 -0
- package/dist/durable/index.d.ts +10 -0
- package/dist/durable/index.d.ts.map +1 -0
- package/dist/durable/index.js +9 -0
- package/dist/durable/index.js.map +1 -0
- package/dist/durable/workflow.d.ts +165 -0
- package/dist/durable/workflow.d.ts.map +1 -0
- package/dist/durable/workflow.js +224 -0
- package/dist/durable/workflow.js.map +1 -0
- package/dist/interview/classification.d.ts +16 -0
- package/dist/interview/classification.d.ts.map +1 -0
- package/dist/interview/classification.js +25 -0
- package/dist/interview/classification.js.map +1 -0
- package/dist/interview/composition.d.ts +12 -0
- package/dist/interview/composition.d.ts.map +1 -0
- package/dist/interview/composition.js +19 -0
- package/dist/interview/composition.js.map +1 -0
- package/dist/interview/describe.d.ts +41 -0
- package/dist/interview/describe.d.ts.map +1 -0
- package/dist/interview/describe.js +80 -0
- package/dist/interview/describe.js.map +1 -0
- package/dist/interview/deviation.d.ts +91 -0
- package/dist/interview/deviation.d.ts.map +1 -0
- package/dist/interview/deviation.js +137 -0
- package/dist/interview/deviation.js.map +1 -0
- package/dist/interview/extraction.d.ts +32 -0
- package/dist/interview/extraction.d.ts.map +1 -0
- package/dist/interview/extraction.js +102 -0
- package/dist/interview/extraction.js.map +1 -0
- package/dist/interview/index.d.ts +25 -0
- package/dist/interview/index.d.ts.map +1 -0
- package/dist/interview/index.js +22 -0
- package/dist/interview/index.js.map +1 -0
- package/dist/interview/macros.d.ts +91 -0
- package/dist/interview/macros.d.ts.map +1 -0
- package/dist/interview/macros.js +138 -0
- package/dist/interview/macros.js.map +1 -0
- package/dist/interview/preambles.d.ts +18 -0
- package/dist/interview/preambles.d.ts.map +1 -0
- package/dist/interview/preambles.js +93 -0
- package/dist/interview/preambles.js.map +1 -0
- package/dist/interview/progress.d.ts +31 -0
- package/dist/interview/progress.d.ts.map +1 -0
- package/dist/interview/progress.js +51 -0
- package/dist/interview/progress.js.map +1 -0
- package/dist/interview/prompt.d.ts +20 -0
- package/dist/interview/prompt.d.ts.map +1 -0
- package/dist/interview/prompt.js +58 -0
- package/dist/interview/prompt.js.map +1 -0
- package/dist/phases/aggregate/assumptions.d.ts +14 -0
- package/dist/phases/aggregate/assumptions.d.ts.map +1 -0
- package/dist/phases/aggregate/assumptions.js +33 -0
- package/dist/phases/aggregate/assumptions.js.map +1 -0
- package/dist/phases/aggregate/findings.d.ts +10 -0
- package/dist/phases/aggregate/findings.d.ts.map +1 -0
- package/dist/phases/aggregate/findings.js +20 -0
- package/dist/phases/aggregate/findings.js.map +1 -0
- package/dist/phases/aggregate/goals.d.ts +28 -0
- package/dist/phases/aggregate/goals.d.ts.map +1 -0
- package/dist/phases/aggregate/goals.js +74 -0
- package/dist/phases/aggregate/goals.js.map +1 -0
- package/dist/phases/aggregate/index.d.ts +128 -0
- package/dist/phases/aggregate/index.d.ts.map +1 -0
- package/dist/phases/aggregate/index.js +165 -0
- package/dist/phases/aggregate/index.js.map +1 -0
- package/dist/phases/aggregate/pam.d.ts +19 -0
- package/dist/phases/aggregate/pam.d.ts.map +1 -0
- package/dist/phases/aggregate/pam.js +37 -0
- package/dist/phases/aggregate/pam.js.map +1 -0
- package/dist/phases/aggregate/scope.d.ts +24 -0
- package/dist/phases/aggregate/scope.d.ts.map +1 -0
- package/dist/phases/aggregate/scope.js +67 -0
- package/dist/phases/aggregate/scope.js.map +1 -0
- package/dist/phases/aggregate/shared.d.ts +16 -0
- package/dist/phases/aggregate/shared.d.ts.map +1 -0
- package/dist/phases/aggregate/shared.js +26 -0
- package/dist/phases/aggregate/shared.js.map +1 -0
- package/dist/phases/aggregate/stakeholders.d.ts +27 -0
- package/dist/phases/aggregate/stakeholders.d.ts.map +1 -0
- package/dist/phases/aggregate/stakeholders.js +90 -0
- package/dist/phases/aggregate/stakeholders.js.map +1 -0
- package/dist/phases/aggregate/waitingRoom.d.ts +16 -0
- package/dist/phases/aggregate/waitingRoom.d.ts.map +1 -0
- package/dist/phases/aggregate/waitingRoom.js +32 -0
- package/dist/phases/aggregate/waitingRoom.js.map +1 -0
- package/dist/phases/assumptions.d.ts +19 -0
- package/dist/phases/assumptions.d.ts.map +1 -0
- package/dist/phases/assumptions.js +224 -0
- package/dist/phases/assumptions.js.map +1 -0
- package/dist/phases/configuration.d.ts +8 -0
- package/dist/phases/configuration.d.ts.map +1 -0
- package/dist/phases/configuration.js +14 -0
- package/dist/phases/configuration.js.map +1 -0
- package/dist/phases/goals.d.ts +15 -0
- package/dist/phases/goals.d.ts.map +1 -0
- package/dist/phases/goals.js +297 -0
- package/dist/phases/goals.js.map +1 -0
- package/dist/phases/index.d.ts +21 -0
- package/dist/phases/index.d.ts.map +1 -0
- package/dist/phases/index.js +56 -0
- package/dist/phases/index.js.map +1 -0
- package/dist/phases/opening.d.ts +12 -0
- package/dist/phases/opening.d.ts.map +1 -0
- package/dist/phases/opening.js +99 -0
- package/dist/phases/opening.js.map +1 -0
- package/dist/phases/purpose.d.ts +17 -0
- package/dist/phases/purpose.d.ts.map +1 -0
- package/dist/phases/purpose.js +207 -0
- package/dist/phases/purpose.js.map +1 -0
- package/dist/phases/schema.d.ts +861 -0
- package/dist/phases/schema.d.ts.map +1 -0
- package/dist/phases/schema.js +157 -0
- package/dist/phases/schema.js.map +1 -0
- package/dist/phases/scope.d.ts +18 -0
- package/dist/phases/scope.d.ts.map +1 -0
- package/dist/phases/scope.js +440 -0
- package/dist/phases/scope.js.map +1 -0
- package/dist/phases/session/archive.d.ts +19 -0
- package/dist/phases/session/archive.d.ts.map +1 -0
- package/dist/phases/session/archive.js +49 -0
- package/dist/phases/session/archive.js.map +1 -0
- package/dist/phases/session/file.d.ts +31 -0
- package/dist/phases/session/file.d.ts.map +1 -0
- package/dist/phases/session/file.js +113 -0
- package/dist/phases/session/file.js.map +1 -0
- package/dist/phases/session/index.d.ts +8 -0
- package/dist/phases/session/index.d.ts.map +1 -0
- package/dist/phases/session/index.js +8 -0
- package/dist/phases/session/index.js.map +1 -0
- package/dist/phases/session/persistence.d.ts +30 -0
- package/dist/phases/session/persistence.d.ts.map +1 -0
- package/dist/phases/session/persistence.js +91 -0
- package/dist/phases/session/persistence.js.map +1 -0
- package/dist/phases/shared.d.ts +64 -0
- package/dist/phases/shared.d.ts.map +1 -0
- package/dist/phases/shared.js +100 -0
- package/dist/phases/shared.js.map +1 -0
- package/dist/phases/stakeholders.d.ts +17 -0
- package/dist/phases/stakeholders.d.ts.map +1 -0
- package/dist/phases/stakeholders.js +370 -0
- package/dist/phases/stakeholders.js.map +1 -0
- package/dist/phases/validation.d.ts +13 -0
- package/dist/phases/validation.d.ts.map +1 -0
- package/dist/phases/validation.js +130 -0
- package/dist/phases/validation.js.map +1 -0
- package/dist/skill/adapter.d.ts +16 -0
- package/dist/skill/adapter.d.ts.map +1 -0
- package/dist/skill/adapter.js +278 -0
- package/dist/skill/adapter.js.map +1 -0
- package/dist/skill/index.d.ts +12 -0
- package/dist/skill/index.d.ts.map +1 -0
- package/dist/skill/index.js +11 -0
- package/dist/skill/index.js.map +1 -0
- package/dist/skill/log.d.ts +18 -0
- package/dist/skill/log.d.ts.map +1 -0
- package/dist/skill/log.js +53 -0
- package/dist/skill/log.js.map +1 -0
- package/package.json +83 -0
- package/skills/clarifying-ideas/SKILL.md +97 -0
- package/skills/clarifying-ideas/scripts/clarifying-ideas.cjs +594 -0
- package/skills/clarifying-ideas/scripts/clarifying-ideas.cjs.map +6 -0
- package/skills/project-brief/SKILL.md +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexandru Botez
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Clarifying Ideas
|
|
2
|
+
|
|
3
|
+
An agent skill that helps you turn vague ideas into structured requirements.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/alexbot/clarifying-ideas/actions/workflows/ci.yml)
|
|
6
|
+
[](https://www.npmjs.com/package/@alex.botez/clarifying-ideas)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
## The Problem
|
|
10
|
+
|
|
11
|
+
Most people either vibe-code, start building and figure it out along the way, or paste a one-line prompt and hope what comes back is a spec. Both skip the step before planning: figuring out what success looks like, who cares, where the boundaries are, and which assumptions will bite you later.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
Most projects start here
|
|
15
|
+
↓
|
|
16
|
+
┌──────┐ ┌────────┐ ┌───────┐ ┌──────┐ ┌────────┐
|
|
17
|
+
? → │ Plan │ → │ Design │ → │ Build │ → │ Test │ → │ Launch │
|
|
18
|
+
└──────┘ └────────┘ └───────┘ └──────┘ └────────┘
|
|
19
|
+
↑
|
|
20
|
+
Clarifying Ideas sits here.
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
That step has methods (qualitative research, goal modeling, structured interviews) but they depend on trained facilitators and workshops. Solo developers, founders, and small teams skip it entirely, and discover the gaps mid-build.
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx skills add alexbot/clarifying-ideas -a claude-code # Claude Code
|
|
29
|
+
npx skills add alexbot/clarifying-ideas -a cursor # Cursor
|
|
30
|
+
npx skills add alexbot/clarifying-ideas -a github-copilot # GitHub Copilot
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Then `/clarifying-ideas` in your agent. Any agent that supports [agentskills.io](https://agentskills.io) works. See the [full list](https://www.npmjs.com/package/skills#supported-agents).
|
|
34
|
+
|
|
35
|
+
## What It Does
|
|
36
|
+
|
|
37
|
+
Clarifying Ideas asks the right questions, 25–32 across seven phases, and you control every answer. It moves you from a vague idea to a scoped project definition.
|
|
38
|
+
|
|
39
|
+
- Catches gaps you'd miss on your own: undefined success criteria, wrong assumptions, conflicting premises nobody stated
|
|
40
|
+
- Every goal, stakeholder, scope decision, and assumption traces back to the conversation turn that produced it
|
|
41
|
+
- AI flags ambiguity, never self-resolves. You decide everything
|
|
42
|
+
|
|
43
|
+
## Example
|
|
44
|
+
|
|
45
|
+
The vague idea:
|
|
46
|
+
|
|
47
|
+
> *"Our local library branch is losing visitors and the city might close it. I want to help revive it."*
|
|
48
|
+
|
|
49
|
+
What AI generates from that prompt, versus what emerges after 28 Clarifying Ideas questions:
|
|
50
|
+
|
|
51
|
+
| | AI-generated | After Clarifying Ideas |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| **Purpose** | **Increase traffic by 40%** through events, outreach, and digital resources | **Determine whether the library is what the neighborhood actually needs** |
|
|
54
|
+
| **Goals** | 8 goals with **invented metrics**: 2,500 monthly visitors, $15K fundraising, 30% card registration increase | 3 goals that **flag unknowns**: what patrons actually need, what the city's closure criteria are, who the target visitors should be |
|
|
55
|
+
| **Scope** | **Execution**: launch 5 programs, recruit 15 volunteers, secure grants | **Research**: talk to families, interview city council, assess whether the library is even the right solution |
|
|
56
|
+
| **Insight** | "The library is **a critical community asset**" (stated as fact) | "I never stopped to ask **whether the library is actually what the neighborhood needs**" |
|
|
57
|
+
|
|
58
|
+
[AI-generated brief](docs/examples/library.brief.generated.md) · [Clarifying Ideas brief](docs/examples/library.brief.md) · [More examples](docs/examples/)
|
|
59
|
+
|
|
60
|
+
## Output
|
|
61
|
+
|
|
62
|
+
The interview produces two artifacts:
|
|
63
|
+
|
|
64
|
+
- **Session file** (`.clarifying-ideas/session.yaml`). YAML with every goal, stakeholder, scope item, and assumption traced to its conversation turn. Designed as input for spec-driven development tools or any pipeline that needs structured intent.
|
|
65
|
+
- **Project brief.** Run `/project-brief` on the session to generate a readable markdown summary for stakeholder pitches, project kickoffs, or business plans.
|
|
66
|
+
|
|
67
|
+
The session file lives in your project directory. AI coding agents (Claude Code, Cursor, Aider, etc.) can read it directly — no conversion or extra setup needed. Point your agent at the file and it has the full structured context from the interview.
|
|
68
|
+
|
|
69
|
+
## How It Works
|
|
70
|
+
|
|
71
|
+
The interview is complex: 7 phases, state persistence, extraction cycles, deviation handling. The phases are opening, purpose, goals, stakeholders, scope, assumptions, and validation. Rather than relying on the model to follow a long prompt correctly, Clarifying Ideas splits the work. A compiled script handles all process decisions (what to ask, when to transition, how to store artifacts) while the model handles only semantic work (understanding what you said, extracting meaning, composing follow-ups). The model can't skip phases or lose track; the script drives.
|
|
72
|
+
|
|
73
|
+
Interview techniques draw on Kvale & Patton (semi-structured interviewing), Miller & Rollnick (motivational interviewing), Reynolds & Gutman (means-end laddering), and KAOS (goal decomposition). See [docs/decisions/](docs/decisions/) for the full architecture story.
|
|
74
|
+
|
|
75
|
+
## Security
|
|
76
|
+
|
|
77
|
+
Clarifying Ideas runs locally. No telemetry, no analytics, no data sent anywhere. There are no postinstall scripts — `npm install` runs nothing. All writes go to `.clarifying-ideas/` inside your project directory; nothing touches shared caches, home directories, or system paths.
|
|
78
|
+
|
|
79
|
+
## Development
|
|
80
|
+
|
|
81
|
+
Requires **Node 22+**.
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npm install
|
|
85
|
+
npm run build # TypeScript compilation
|
|
86
|
+
npm run build:skill # esbuild bundle → dist/skill/
|
|
87
|
+
npx vitest run # Run tests
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Contributing
|
|
91
|
+
|
|
92
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, architecture, and how to pick up work.
|
|
93
|
+
|
|
94
|
+
## License
|
|
95
|
+
|
|
96
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable workflow framework — public barrel.
|
|
3
|
+
*
|
|
4
|
+
* Memoized coroutine execution with suspend/resume. See workflow.ts for the
|
|
5
|
+
* full implementation; this file is the public surface for cross-layer and
|
|
6
|
+
* external consumers.
|
|
7
|
+
*/
|
|
8
|
+
export { Suspend, NonDeterminismError, DuplicateCallIdError, WorkflowContext, execute, } from "./workflow.js";
|
|
9
|
+
export type { StateEntry, WorkflowStatus, WorkflowState, StatePersistence, InferRequest, InferStep, PromptRequest, PromptStep, Prompt, Resolver, Workflow, FidelityDetail, FidelityResult, ExecutionResult, } from "./workflow.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/durable/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,OAAO,GACR,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,UAAU,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,aAAa,EACb,UAAU,EACV,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable workflow framework — public barrel.
|
|
3
|
+
*
|
|
4
|
+
* Memoized coroutine execution with suspend/resume. See workflow.ts for the
|
|
5
|
+
* full implementation; this file is the public surface for cross-layer and
|
|
6
|
+
* external consumers.
|
|
7
|
+
*/
|
|
8
|
+
export { Suspend, NonDeterminismError, DuplicateCallIdError, WorkflowContext, execute, } from "./workflow.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/durable/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,OAAO,GACR,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable workflow framework — memoized coroutine execution with suspend/resume.
|
|
3
|
+
*
|
|
4
|
+
* Workflows call infer (LLM) and prompt (user) through a context object. All calls
|
|
5
|
+
* are logged to an ordered state array; on re-execution, recorded values replay
|
|
6
|
+
* and only new calls hit the resolver. Any call can suspend via Suspend throw,
|
|
7
|
+
* which persists the suspension point and propagates to the caller.
|
|
8
|
+
*/
|
|
9
|
+
/** Thrown by a resolver (or call fn) to signal that a call cannot be fulfilled now. */
|
|
10
|
+
export declare class Suspend {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly value?: unknown | undefined;
|
|
13
|
+
constructor(id: string, value?: unknown | undefined);
|
|
14
|
+
}
|
|
15
|
+
/** Thrown when a replayed call id doesn't match the recorded sequence. */
|
|
16
|
+
export declare class NonDeterminismError extends Error {
|
|
17
|
+
constructor(position: number, expected: string, got: string);
|
|
18
|
+
}
|
|
19
|
+
/** Thrown when the same call id is used more than once in a single execution. */
|
|
20
|
+
export declare class DuplicateCallIdError extends Error {
|
|
21
|
+
constructor(id: string);
|
|
22
|
+
}
|
|
23
|
+
/** A single entry in the state log — either completed (has value) or suspended. */
|
|
24
|
+
export type StateEntry = {
|
|
25
|
+
id: string;
|
|
26
|
+
value: unknown;
|
|
27
|
+
} | {
|
|
28
|
+
id: string;
|
|
29
|
+
suspended: true;
|
|
30
|
+
};
|
|
31
|
+
/** Lifecycle status of a workflow execution. */
|
|
32
|
+
export type WorkflowStatus = "running" | "suspended" | "completed" | "failed";
|
|
33
|
+
/** Serializable snapshot of a workflow's progress — status plus ordered call log. */
|
|
34
|
+
export interface WorkflowState {
|
|
35
|
+
status: WorkflowStatus;
|
|
36
|
+
entries: StateEntry[];
|
|
37
|
+
}
|
|
38
|
+
/** Storage adapter for persisting workflow state between executions. */
|
|
39
|
+
export interface StatePersistence {
|
|
40
|
+
load(): WorkflowState | null;
|
|
41
|
+
save(state: WorkflowState): void;
|
|
42
|
+
/** Create initial empty state with "running" status. */
|
|
43
|
+
initialize(): void;
|
|
44
|
+
/** Transition workflow to a new status. */
|
|
45
|
+
setStatus(status: WorkflowStatus): void;
|
|
46
|
+
}
|
|
47
|
+
/** Payload for an infer call — semantic processing by the resolver (typically LLM). */
|
|
48
|
+
export interface InferRequest {
|
|
49
|
+
message: string;
|
|
50
|
+
schema?: Record<string, unknown>;
|
|
51
|
+
}
|
|
52
|
+
/** Phantom brand — carries result type without runtime presence. */
|
|
53
|
+
declare const INFER_STEP_RESULT: unique symbol;
|
|
54
|
+
/** Pre-built infer request with embedded id and phantom return type. */
|
|
55
|
+
export interface InferStep<T = unknown> extends InferRequest {
|
|
56
|
+
readonly id: string;
|
|
57
|
+
readonly [INFER_STEP_RESULT]?: T;
|
|
58
|
+
}
|
|
59
|
+
/** Payload for a prompt call — user-facing message with optional suggested answers. */
|
|
60
|
+
export interface PromptRequest {
|
|
61
|
+
message: string;
|
|
62
|
+
suggestions?: string[];
|
|
63
|
+
}
|
|
64
|
+
/** Pre-built prompt request with embedded id — mirrors InferStep for prompt calls. */
|
|
65
|
+
export interface PromptStep extends PromptRequest {
|
|
66
|
+
readonly id: string;
|
|
67
|
+
}
|
|
68
|
+
/** A prompt emitted by the framework — either an infer or prompt request tagged with its call id. */
|
|
69
|
+
export type Prompt = {
|
|
70
|
+
id: string;
|
|
71
|
+
type: "infer";
|
|
72
|
+
request: InferRequest;
|
|
73
|
+
} | {
|
|
74
|
+
id: string;
|
|
75
|
+
type: "prompt";
|
|
76
|
+
request: PromptRequest;
|
|
77
|
+
};
|
|
78
|
+
/** Callback that fulfills prompts — the single adapter interface for all non-compute calls. */
|
|
79
|
+
export type Resolver = (prompt: Prompt) => Promise<unknown>;
|
|
80
|
+
/** Per-extraction mismatch detail — which keys were expected but missing. */
|
|
81
|
+
export interface FidelityDetail {
|
|
82
|
+
id: string;
|
|
83
|
+
expectedKeys: string[];
|
|
84
|
+
actualKeys: string[];
|
|
85
|
+
missingKeys: string[];
|
|
86
|
+
reason?: "non-object" | "missing-keys";
|
|
87
|
+
}
|
|
88
|
+
/** Accumulated fidelity result across all schema-bearing infer calls. */
|
|
89
|
+
export interface FidelityResult {
|
|
90
|
+
checked: number;
|
|
91
|
+
mismatched: number;
|
|
92
|
+
details: FidelityDetail[];
|
|
93
|
+
}
|
|
94
|
+
/** Result of a workflow execution — extensible container for execution-level concerns. */
|
|
95
|
+
export interface ExecutionResult {
|
|
96
|
+
fidelity: FidelityResult;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Execution context passed to workflow functions.
|
|
100
|
+
*
|
|
101
|
+
* Provides three call primitives (call, infer, prompt) that memoize results
|
|
102
|
+
* in an ordered state log and replay on re-execution.
|
|
103
|
+
*/
|
|
104
|
+
export declare class WorkflowContext {
|
|
105
|
+
private persistence;
|
|
106
|
+
private resolver;
|
|
107
|
+
private cursor;
|
|
108
|
+
private seen;
|
|
109
|
+
private state;
|
|
110
|
+
private fidelity;
|
|
111
|
+
private lastPrompt;
|
|
112
|
+
constructor(persistence: StatePersistence, resolver: Resolver);
|
|
113
|
+
/**
|
|
114
|
+
* Deterministic compute — runs fn, memoizes, replays from log on re-execution.
|
|
115
|
+
* If fn throws Suspend, a suspended entry is written before propagating.
|
|
116
|
+
*/
|
|
117
|
+
call<T>(id: string, fn: () => T | Promise<T>): Promise<T>;
|
|
118
|
+
/** ID of the most recent prompt() call, or null before any prompt. */
|
|
119
|
+
get lastPromptId(): string | null;
|
|
120
|
+
get currentSource(): {
|
|
121
|
+
promptId: string;
|
|
122
|
+
} | undefined;
|
|
123
|
+
/** Accumulated fidelity result for all schema-bearing infer calls in this execution. */
|
|
124
|
+
fidelityResult(): FidelityResult;
|
|
125
|
+
/** Non-deterministic semantic processing — delegates to resolver, memoized. */
|
|
126
|
+
infer<T>(step: InferStep<T>): Promise<T>;
|
|
127
|
+
infer<T>(id: string, request: InferRequest): Promise<T>;
|
|
128
|
+
/** Check result keys against schema keys; accumulate fidelity counters. */
|
|
129
|
+
private checkFidelity;
|
|
130
|
+
/** Human interaction — delegates to resolver, memoized. May cause suspension. */
|
|
131
|
+
prompt(step: PromptStep): Promise<string>;
|
|
132
|
+
prompt(id: string, request: PromptRequest): Promise<string>;
|
|
133
|
+
}
|
|
134
|
+
/** A workflow function — receives a context, performs calls, returns when complete. */
|
|
135
|
+
export type Workflow = (ctx: WorkflowContext) => Promise<void>;
|
|
136
|
+
/**
|
|
137
|
+
* Run (or resume) a workflow. Replays memoized calls, then continues execution.
|
|
138
|
+
* Returns execution result on completion. Throws Suspend on suspension (already
|
|
139
|
+
* persisted by the context). Throws other errors on failure.
|
|
140
|
+
*
|
|
141
|
+
* If status is already `completed`, returns `{ fidelity: EMPTY_FIDELITY }`
|
|
142
|
+
* without re-executing. Callers that need to distinguish fresh completion
|
|
143
|
+
* from a no-op should check `persistence.status()` before calling.
|
|
144
|
+
*
|
|
145
|
+
* Suspension is a throw, not a return. A `Suspend` instance carries the id of
|
|
146
|
+
* the suspending call and the pending `Prompt` payload as its `value` field.
|
|
147
|
+
* Callers must handle both paths:
|
|
148
|
+
*
|
|
149
|
+
* try {
|
|
150
|
+
* const result = await execute(persistence, workflow, resolver);
|
|
151
|
+
* // Workflow completed — `result.fidelity` has the extraction stats.
|
|
152
|
+
* } catch (e) {
|
|
153
|
+
* if (e instanceof Suspend) {
|
|
154
|
+
* // Workflow paused on a prompt — `e.value` is the `Prompt` payload,
|
|
155
|
+
* // `e.id` is the suspended call's id. Persist-and-return so the
|
|
156
|
+
* // next invocation resumes from this point.
|
|
157
|
+
* } else {
|
|
158
|
+
* // Real failure — persistence has already been flagged "failed".
|
|
159
|
+
* throw e;
|
|
160
|
+
* }
|
|
161
|
+
* }
|
|
162
|
+
*/
|
|
163
|
+
export declare function execute(persistence: StatePersistence, workflow: Workflow, resolver: Resolver): Promise<ExecutionResult>;
|
|
164
|
+
export {};
|
|
165
|
+
//# sourceMappingURL=workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/durable/workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable workflow framework — memoized coroutine execution with suspend/resume.
|
|
3
|
+
*
|
|
4
|
+
* Workflows call infer (LLM) and prompt (user) through a context object. All calls
|
|
5
|
+
* are logged to an ordered state array; on re-execution, recorded values replay
|
|
6
|
+
* and only new calls hit the resolver. Any call can suspend via Suspend throw,
|
|
7
|
+
* which persists the suspension point and propagates to the caller.
|
|
8
|
+
*/
|
|
9
|
+
// Errors
|
|
10
|
+
/** Thrown by a resolver (or call fn) to signal that a call cannot be fulfilled now. */
|
|
11
|
+
export class Suspend {
|
|
12
|
+
id;
|
|
13
|
+
value;
|
|
14
|
+
constructor(id, value) {
|
|
15
|
+
this.id = id;
|
|
16
|
+
this.value = value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** Thrown when a replayed call id doesn't match the recorded sequence. */
|
|
20
|
+
export class NonDeterminismError extends Error {
|
|
21
|
+
constructor(position, expected, got) {
|
|
22
|
+
super(`Non-determinism at position ${position}: expected "${expected}", got "${got}"`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** Thrown when the same call id is used more than once in a single execution. */
|
|
26
|
+
export class DuplicateCallIdError extends Error {
|
|
27
|
+
constructor(id) {
|
|
28
|
+
super(`Duplicate call id: "${id}"`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Context
|
|
32
|
+
/**
|
|
33
|
+
* Execution context passed to workflow functions.
|
|
34
|
+
*
|
|
35
|
+
* Provides three call primitives (call, infer, prompt) that memoize results
|
|
36
|
+
* in an ordered state log and replay on re-execution.
|
|
37
|
+
*/
|
|
38
|
+
export class WorkflowContext {
|
|
39
|
+
persistence;
|
|
40
|
+
resolver;
|
|
41
|
+
cursor = 0;
|
|
42
|
+
seen = new Set();
|
|
43
|
+
state;
|
|
44
|
+
fidelity = { checked: 0, mismatched: 0, details: [] };
|
|
45
|
+
lastPrompt = null;
|
|
46
|
+
constructor(persistence, resolver) {
|
|
47
|
+
this.persistence = persistence;
|
|
48
|
+
this.resolver = resolver;
|
|
49
|
+
const state = persistence.load();
|
|
50
|
+
if (!state)
|
|
51
|
+
throw new Error("WorkflowContext requires initialized persistence; call persistence.initialize() first");
|
|
52
|
+
this.state = state;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Deterministic compute — runs fn, memoizes, replays from log on re-execution.
|
|
56
|
+
* If fn throws Suspend, a suspended entry is written before propagating.
|
|
57
|
+
*/
|
|
58
|
+
async call(id, fn) {
|
|
59
|
+
// Replay path: entry exists in state log
|
|
60
|
+
if (this.cursor < this.state.entries.length) {
|
|
61
|
+
const entry = this.state.entries[this.cursor];
|
|
62
|
+
if (entry.id !== id)
|
|
63
|
+
throw new NonDeterminismError(this.cursor, entry.id, id);
|
|
64
|
+
this.seen.add(entry.id);
|
|
65
|
+
this.cursor++;
|
|
66
|
+
// Suspended entry — try to fulfill
|
|
67
|
+
if ("suspended" in entry) {
|
|
68
|
+
try {
|
|
69
|
+
const result = await fn();
|
|
70
|
+
this.state.entries[this.cursor - 1] = { id, value: result };
|
|
71
|
+
this.persistence.save(this.state);
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
if (e instanceof Suspend) {
|
|
76
|
+
this.state.status = "suspended";
|
|
77
|
+
this.persistence.save(this.state);
|
|
78
|
+
throw e;
|
|
79
|
+
}
|
|
80
|
+
throw e;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Completed entry — return cached value
|
|
84
|
+
return entry.value;
|
|
85
|
+
}
|
|
86
|
+
// First-hit path: new call not yet in state log
|
|
87
|
+
if (this.seen.has(id))
|
|
88
|
+
throw new DuplicateCallIdError(id);
|
|
89
|
+
this.seen.add(id);
|
|
90
|
+
try {
|
|
91
|
+
const result = await fn();
|
|
92
|
+
this.state.entries.push({ id, value: result });
|
|
93
|
+
this.cursor++;
|
|
94
|
+
this.persistence.save(this.state);
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
if (e instanceof Suspend) {
|
|
99
|
+
this.state.entries.push({ id, suspended: true });
|
|
100
|
+
this.state.status = "suspended";
|
|
101
|
+
this.cursor++;
|
|
102
|
+
this.persistence.save(this.state);
|
|
103
|
+
throw e;
|
|
104
|
+
}
|
|
105
|
+
throw e;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** ID of the most recent prompt() call, or null before any prompt. */
|
|
109
|
+
get lastPromptId() { return this.lastPrompt; }
|
|
110
|
+
get currentSource() {
|
|
111
|
+
return this.lastPrompt ? { promptId: this.lastPrompt } : undefined;
|
|
112
|
+
}
|
|
113
|
+
/** Accumulated fidelity result for all schema-bearing infer calls in this execution. */
|
|
114
|
+
fidelityResult() {
|
|
115
|
+
return this.fidelity;
|
|
116
|
+
}
|
|
117
|
+
async infer(first, second) {
|
|
118
|
+
const id = typeof first === "string" ? first : first.id;
|
|
119
|
+
const request = typeof first === "string"
|
|
120
|
+
? second
|
|
121
|
+
: { message: first.message, schema: first.schema };
|
|
122
|
+
const prompt = { id, type: "infer", request };
|
|
123
|
+
const result = await this.call(id, () => this.resolver(prompt));
|
|
124
|
+
if (request.schema && (result == null || typeof result !== "object")) {
|
|
125
|
+
const expectedKeys = Object.keys(request.schema);
|
|
126
|
+
this.fidelity.checked++;
|
|
127
|
+
this.fidelity.mismatched++;
|
|
128
|
+
this.fidelity.details.push({
|
|
129
|
+
id, expectedKeys, actualKeys: [], missingKeys: expectedKeys, reason: "non-object",
|
|
130
|
+
});
|
|
131
|
+
return {};
|
|
132
|
+
}
|
|
133
|
+
if (request.schema && result != null && typeof result === "object") {
|
|
134
|
+
this.checkFidelity(id, request.schema, result);
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
/** Check result keys against schema keys; accumulate fidelity counters. */
|
|
139
|
+
checkFidelity(id, schema, result) {
|
|
140
|
+
const expectedKeys = Object.keys(schema);
|
|
141
|
+
const actualKeys = Object.keys(result);
|
|
142
|
+
const missingKeys = expectedKeys.filter((k) => !(k in result));
|
|
143
|
+
this.fidelity.checked++;
|
|
144
|
+
if (missingKeys.length > 0) {
|
|
145
|
+
this.fidelity.mismatched++;
|
|
146
|
+
this.fidelity.details.push({ id, expectedKeys, actualKeys, missingKeys, reason: "missing-keys" });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async prompt(first, second) {
|
|
150
|
+
const id = typeof first === "string" ? first : first.id;
|
|
151
|
+
const request = typeof first === "string"
|
|
152
|
+
? second
|
|
153
|
+
: { message: first.message, ...(first.suggestions ? { suggestions: first.suggestions } : {}) };
|
|
154
|
+
request.message = normalizeMessage(request.message);
|
|
155
|
+
this.lastPrompt = id;
|
|
156
|
+
const p = { id, type: "prompt", request };
|
|
157
|
+
const result = await this.call(id, () => this.resolver(p));
|
|
158
|
+
if (typeof result !== "string")
|
|
159
|
+
return "";
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function normalizeMessage(text) {
|
|
164
|
+
return text
|
|
165
|
+
.split("\n")
|
|
166
|
+
.map((line) => line.trim())
|
|
167
|
+
.join("\n")
|
|
168
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
169
|
+
.trim();
|
|
170
|
+
}
|
|
171
|
+
// Execute
|
|
172
|
+
const EMPTY_FIDELITY = { checked: 0, mismatched: 0, details: [] };
|
|
173
|
+
/**
|
|
174
|
+
* Run (or resume) a workflow. Replays memoized calls, then continues execution.
|
|
175
|
+
* Returns execution result on completion. Throws Suspend on suspension (already
|
|
176
|
+
* persisted by the context). Throws other errors on failure.
|
|
177
|
+
*
|
|
178
|
+
* If status is already `completed`, returns `{ fidelity: EMPTY_FIDELITY }`
|
|
179
|
+
* without re-executing. Callers that need to distinguish fresh completion
|
|
180
|
+
* from a no-op should check `persistence.status()` before calling.
|
|
181
|
+
*
|
|
182
|
+
* Suspension is a throw, not a return. A `Suspend` instance carries the id of
|
|
183
|
+
* the suspending call and the pending `Prompt` payload as its `value` field.
|
|
184
|
+
* Callers must handle both paths:
|
|
185
|
+
*
|
|
186
|
+
* try {
|
|
187
|
+
* const result = await execute(persistence, workflow, resolver);
|
|
188
|
+
* // Workflow completed — `result.fidelity` has the extraction stats.
|
|
189
|
+
* } catch (e) {
|
|
190
|
+
* if (e instanceof Suspend) {
|
|
191
|
+
* // Workflow paused on a prompt — `e.value` is the `Prompt` payload,
|
|
192
|
+
* // `e.id` is the suspended call's id. Persist-and-return so the
|
|
193
|
+
* // next invocation resumes from this point.
|
|
194
|
+
* } else {
|
|
195
|
+
* // Real failure — persistence has already been flagged "failed".
|
|
196
|
+
* throw e;
|
|
197
|
+
* }
|
|
198
|
+
* }
|
|
199
|
+
*/
|
|
200
|
+
export async function execute(persistence, workflow, resolver) {
|
|
201
|
+
const state = persistence.load();
|
|
202
|
+
if (!state) {
|
|
203
|
+
persistence.initialize();
|
|
204
|
+
}
|
|
205
|
+
else if (state.status === "completed") {
|
|
206
|
+
return { fidelity: EMPTY_FIDELITY };
|
|
207
|
+
}
|
|
208
|
+
else if (state.status !== "running") {
|
|
209
|
+
persistence.setStatus("running");
|
|
210
|
+
}
|
|
211
|
+
const ctx = new WorkflowContext(persistence, resolver);
|
|
212
|
+
try {
|
|
213
|
+
await workflow(ctx);
|
|
214
|
+
persistence.setStatus("completed");
|
|
215
|
+
return { fidelity: ctx.fidelityResult() };
|
|
216
|
+
}
|
|
217
|
+
catch (e) {
|
|
218
|
+
if (e instanceof Suspend)
|
|
219
|
+
throw e;
|
|
220
|
+
persistence.setStatus("failed");
|
|
221
|
+
throw e;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/durable/workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review classification — LLM call that classifies the respondent's reaction
|
|
3
|
+
* to a presented item list (confirmed / removed / new items). Schema shape is
|
|
4
|
+
* phase-specific and passed by the caller.
|
|
5
|
+
*
|
|
6
|
+
* The base confirmation schema (`ConfirmClassifySchema` with `targetId`) and
|
|
7
|
+
* `ctx.confirm` live in `phases/shared.ts` because the classification takes
|
|
8
|
+
* the RE `Phase` and `Artifacts` types.
|
|
9
|
+
*/
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
declare module "../durable/workflow.js" {
|
|
12
|
+
interface WorkflowContext {
|
|
13
|
+
review<S extends z.ZodObject<any>>(id: string, response: string, itemRef: string, artifactsContext: string, schema: S, ri?: number): Promise<z.infer<S>>;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=classification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classification.d.ts","sourceRoot":"","sources":["../../src/interview/classification.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,QAAQ,wBAAwB,CAAC;IACtC,UAAU,eAAe;QACvB,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;KAC1J;CACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review classification — LLM call that classifies the respondent's reaction
|
|
3
|
+
* to a presented item list (confirmed / removed / new items). Schema shape is
|
|
4
|
+
* phase-specific and passed by the caller.
|
|
5
|
+
*
|
|
6
|
+
* The base confirmation schema (`ConfirmClassifySchema` with `targetId`) and
|
|
7
|
+
* `ctx.confirm` live in `phases/shared.ts` because the classification takes
|
|
8
|
+
* the RE `Phase` and `Artifacts` types.
|
|
9
|
+
*/
|
|
10
|
+
import { WorkflowContext } from "../durable/index.js";
|
|
11
|
+
/** Classify the respondent's reaction to a presented item list (confirmed/removed/new items). */
|
|
12
|
+
WorkflowContext.prototype.review = async function (id, response, itemRef, artifactsContext, schema, ri) {
|
|
13
|
+
const fullId = ri !== undefined ? `${id}-r${ri}` : id;
|
|
14
|
+
return this.extract({
|
|
15
|
+
id: fullId,
|
|
16
|
+
response,
|
|
17
|
+
artifactsContext,
|
|
18
|
+
schema,
|
|
19
|
+
guidance: `The respondent reacted to the presented list.\n${itemRef ? `Item IDs: ${itemRef}` : "No items existed yet."}`,
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
if (typeof WorkflowContext.prototype.review !== "function") {
|
|
23
|
+
throw new Error("interview/classification.ts self-check failed: WorkflowContext.prototype.review is not a function.");
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=classification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classification.js","sourceRoot":"","sources":["../../src/interview/classification.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAQtD,iGAAiG;AACjG,eAAe,CAAC,SAAS,CAAC,MAAM,GAAG,KAAK,WAAW,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAG;IACrG,MAAM,MAAM,GAAG,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtD,OAAO,IAAI,CAAC,OAAO,CAAC;QAClB,EAAE,EAAE,MAAM;QACV,QAAQ;QACR,gBAAgB;QAChB,MAAM;QACN,QAAQ,EAAE,kDAAkD,OAAO,CAAC,CAAC,CAAC,aAAa,OAAO,EAAE,CAAC,CAAC,CAAC,uBAAuB,EAAE;KACzH,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,IAAI,OAAQ,eAAe,CAAC,SAAgD,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;IACnG,MAAM,IAAI,KAAK,CAAC,oGAAoG,CAAC,CAAC;AACxH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Question composition — LLM call that produces an interview question with
|
|
3
|
+
* optional suggested answers, preceded by the composition quality preamble.
|
|
4
|
+
*/
|
|
5
|
+
import type { ComposeParams } from "./describe.js";
|
|
6
|
+
import type { QuestionContext } from "./prompt.js";
|
|
7
|
+
declare module "../durable/workflow.js" {
|
|
8
|
+
interface WorkflowContext {
|
|
9
|
+
compose(step: ComposeParams): Promise<QuestionContext>;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=composition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composition.d.ts","sourceRoot":"","sources":["../../src/interview/composition.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,QAAQ,wBAAwB,CAAC;IACtC,UAAU,eAAe;QACvB,OAAO,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;KACxD;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Question composition — LLM call that produces an interview question with
|
|
3
|
+
* optional suggested answers, preceded by the composition quality preamble.
|
|
4
|
+
*/
|
|
5
|
+
import { WorkflowContext } from "../durable/index.js";
|
|
6
|
+
import { compositionPreamble } from "./preambles.js";
|
|
7
|
+
/** Compose a question with suggestions; falls back to step.fallback if agent returns empty. */
|
|
8
|
+
WorkflowContext.prototype.compose = async function (step) {
|
|
9
|
+
const compPre = compositionPreamble();
|
|
10
|
+
const enrichedStep = compPre
|
|
11
|
+
? { ...step, message: compPre + "\n\n" + step.message }
|
|
12
|
+
: step;
|
|
13
|
+
const { question, suggestions } = await this.infer(enrichedStep);
|
|
14
|
+
return question ? { question, suggestions } : { question: step.fallback };
|
|
15
|
+
};
|
|
16
|
+
if (typeof WorkflowContext.prototype.compose !== "function") {
|
|
17
|
+
throw new Error("interview/composition.ts self-check failed: WorkflowContext.prototype.compose is not a function.");
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=composition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composition.js","sourceRoot":"","sources":["../../src/interview/composition.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AASrD,+FAA+F;AAC/F,eAAe,CAAC,SAAS,CAAC,OAAO,GAAG,KAAK,WAAW,IAAmB;IACrE,MAAM,OAAO,GAAG,mBAAmB,EAAE,CAAC;IACtC,MAAM,YAAY,GAAG,OAAO;QAC1B,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE;QACvD,CAAC,CAAC,IAAI,CAAC;IACT,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACjE,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC5E,CAAC,CAAC;AAEF,IAAI,OAAQ,eAAe,CAAC,SAAgD,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;IACpG,MAAM,IAAI,KAAK,CAAC,kGAAkG,CAAC,CAAC;AACtH,CAAC"}
|