@tienne/gestalt 0.1.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/CLAUDE.md +203 -0
- package/README.md +60 -0
- package/agents/closure-completer/AGENT.md +32 -0
- package/agents/continuity-judge/AGENT.md +40 -0
- package/agents/ground-mapper/AGENT.md +31 -0
- package/agents/proximity-worker/AGENT.md +33 -0
- package/agents/similarity-crystallizer/AGENT.md +34 -0
- package/dist/agents/closure-completer/AGENT.md +32 -0
- package/dist/agents/continuity-judge/AGENT.md +40 -0
- package/dist/agents/ground-mapper/AGENT.md +31 -0
- package/dist/agents/proximity-worker/AGENT.md +33 -0
- package/dist/agents/similarity-crystallizer/AGENT.md +34 -0
- package/dist/bin/gestalt.d.ts +3 -0
- package/dist/bin/gestalt.d.ts.map +1 -0
- package/dist/bin/gestalt.js +5 -0
- package/dist/bin/gestalt.js.map +1 -0
- package/dist/skills/execute/SKILL.md +84 -0
- package/dist/skills/interview/SKILL.md +82 -0
- package/dist/skills/seed/SKILL.md +92 -0
- package/dist/skills/spec/SKILL.md +92 -0
- package/dist/src/agent/figural-router.d.ts +48 -0
- package/dist/src/agent/figural-router.d.ts.map +1 -0
- package/dist/src/agent/figural-router.js +55 -0
- package/dist/src/agent/figural-router.js.map +1 -0
- package/dist/src/agent/parser.d.ts +3 -0
- package/dist/src/agent/parser.d.ts.map +1 -0
- package/dist/src/agent/parser.js +32 -0
- package/dist/src/agent/parser.js.map +1 -0
- package/dist/src/agent/prompt-resolver.d.ts +17 -0
- package/dist/src/agent/prompt-resolver.d.ts.map +1 -0
- package/dist/src/agent/prompt-resolver.js +31 -0
- package/dist/src/agent/prompt-resolver.js.map +1 -0
- package/dist/src/agent/registry.d.ts +9 -0
- package/dist/src/agent/registry.d.ts.map +1 -0
- package/dist/src/agent/registry.js +22 -0
- package/dist/src/agent/registry.js.map +1 -0
- package/dist/src/cli/commands/interview.d.ts +2 -0
- package/dist/src/cli/commands/interview.d.ts.map +1 -0
- package/dist/src/cli/commands/interview.js +67 -0
- package/dist/src/cli/commands/interview.js.map +1 -0
- package/dist/src/cli/commands/seed.d.ts +4 -0
- package/dist/src/cli/commands/seed.d.ts.map +1 -0
- package/dist/src/cli/commands/seed.js +34 -0
- package/dist/src/cli/commands/seed.js.map +1 -0
- package/dist/src/cli/commands/serve.d.ts +2 -0
- package/dist/src/cli/commands/serve.d.ts.map +1 -0
- package/dist/src/cli/commands/serve.js +5 -0
- package/dist/src/cli/commands/serve.js.map +1 -0
- package/dist/src/cli/commands/spec.d.ts +4 -0
- package/dist/src/cli/commands/spec.d.ts.map +1 -0
- package/dist/src/cli/commands/spec.js +34 -0
- package/dist/src/cli/commands/spec.js.map +1 -0
- package/dist/src/cli/commands/status.d.ts +2 -0
- package/dist/src/cli/commands/status.d.ts.map +1 -0
- package/dist/src/cli/commands/status.js +66 -0
- package/dist/src/cli/commands/status.js.map +1 -0
- package/dist/src/cli/index.d.ts +3 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +39 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/core/config.d.ts +36 -0
- package/dist/src/core/config.d.ts.map +1 -0
- package/dist/src/core/config.js +65 -0
- package/dist/src/core/config.js.map +1 -0
- package/dist/src/core/constants.d.ts +34 -0
- package/dist/src/core/constants.d.ts.map +1 -0
- package/dist/src/core/constants.js +68 -0
- package/dist/src/core/constants.js.map +1 -0
- package/dist/src/core/errors.d.ts +50 -0
- package/dist/src/core/errors.d.ts.map +1 -0
- package/dist/src/core/errors.js +99 -0
- package/dist/src/core/errors.js.map +1 -0
- package/dist/src/core/log.d.ts +5 -0
- package/dist/src/core/log.d.ts.map +1 -0
- package/dist/src/core/log.js +7 -0
- package/dist/src/core/log.js.map +1 -0
- package/dist/src/core/result.d.ts +20 -0
- package/dist/src/core/result.d.ts.map +1 -0
- package/dist/src/core/result.js +43 -0
- package/dist/src/core/result.js.map +1 -0
- package/dist/src/core/types.d.ts +289 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +15 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/events/store.d.ts +22 -0
- package/dist/src/events/store.d.ts.map +1 -0
- package/dist/src/events/store.js +130 -0
- package/dist/src/events/store.js.map +1 -0
- package/dist/src/events/types.d.ts +33 -0
- package/dist/src/events/types.d.ts.map +1 -0
- package/dist/src/events/types.js +35 -0
- package/dist/src/events/types.js.map +1 -0
- package/dist/src/execute/dag-validator.d.ts +7 -0
- package/dist/src/execute/dag-validator.d.ts.map +1 -0
- package/dist/src/execute/dag-validator.js +141 -0
- package/dist/src/execute/dag-validator.js.map +1 -0
- package/dist/src/execute/drift-detector.d.ts +11 -0
- package/dist/src/execute/drift-detector.d.ts.map +1 -0
- package/dist/src/execute/drift-detector.js +111 -0
- package/dist/src/execute/drift-detector.js.map +1 -0
- package/dist/src/execute/impact-identifier.d.ts +12 -0
- package/dist/src/execute/impact-identifier.d.ts.map +1 -0
- package/dist/src/execute/impact-identifier.js +60 -0
- package/dist/src/execute/impact-identifier.js.map +1 -0
- package/dist/src/execute/passthrough-engine.d.ts +181 -0
- package/dist/src/execute/passthrough-engine.d.ts.map +1 -0
- package/dist/src/execute/passthrough-engine.js +795 -0
- package/dist/src/execute/passthrough-engine.js.map +1 -0
- package/dist/src/execute/prompts.d.ts +19 -0
- package/dist/src/execute/prompts.d.ts.map +1 -0
- package/dist/src/execute/prompts.js +505 -0
- package/dist/src/execute/prompts.js.map +1 -0
- package/dist/src/execute/repository.d.ts +30 -0
- package/dist/src/execute/repository.d.ts.map +1 -0
- package/dist/src/execute/repository.js +248 -0
- package/dist/src/execute/repository.js.map +1 -0
- package/dist/src/execute/session.d.ts +34 -0
- package/dist/src/execute/session.d.ts.map +1 -0
- package/dist/src/execute/session.js +273 -0
- package/dist/src/execute/session.js.map +1 -0
- package/dist/src/execute/spec-patch-applier.d.ts +13 -0
- package/dist/src/execute/spec-patch-applier.d.ts.map +1 -0
- package/dist/src/execute/spec-patch-applier.js +83 -0
- package/dist/src/execute/spec-patch-applier.js.map +1 -0
- package/dist/src/execute/spec-patch-validator.d.ts +20 -0
- package/dist/src/execute/spec-patch-validator.d.ts.map +1 -0
- package/dist/src/execute/spec-patch-validator.js +60 -0
- package/dist/src/execute/spec-patch-validator.js.map +1 -0
- package/dist/src/execute/termination-detector.d.ts +20 -0
- package/dist/src/execute/termination-detector.d.ts.map +1 -0
- package/dist/src/execute/termination-detector.js +77 -0
- package/dist/src/execute/termination-detector.js.map +1 -0
- package/dist/src/gestalt/analyzer.d.ts +18 -0
- package/dist/src/gestalt/analyzer.d.ts.map +1 -0
- package/dist/src/gestalt/analyzer.js +59 -0
- package/dist/src/gestalt/analyzer.js.map +1 -0
- package/dist/src/gestalt/principles.d.ts +21 -0
- package/dist/src/gestalt/principles.d.ts.map +1 -0
- package/dist/src/gestalt/principles.js +66 -0
- package/dist/src/gestalt/principles.js.map +1 -0
- package/dist/src/index.d.ts +22 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +22 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interview/ambiguity.d.ts +8 -0
- package/dist/src/interview/ambiguity.d.ts.map +1 -0
- package/dist/src/interview/ambiguity.js +69 -0
- package/dist/src/interview/ambiguity.js.map +1 -0
- package/dist/src/interview/brownfield.d.ts +7 -0
- package/dist/src/interview/brownfield.d.ts.map +1 -0
- package/dist/src/interview/brownfield.js +28 -0
- package/dist/src/interview/brownfield.js.map +1 -0
- package/dist/src/interview/engine.d.ts +31 -0
- package/dist/src/interview/engine.d.ts.map +1 -0
- package/dist/src/interview/engine.js +110 -0
- package/dist/src/interview/engine.js.map +1 -0
- package/dist/src/interview/passthrough-engine.d.ts +52 -0
- package/dist/src/interview/passthrough-engine.d.ts.map +1 -0
- package/dist/src/interview/passthrough-engine.js +174 -0
- package/dist/src/interview/passthrough-engine.js.map +1 -0
- package/dist/src/interview/questions.d.ts +12 -0
- package/dist/src/interview/questions.d.ts.map +1 -0
- package/dist/src/interview/questions.js +54 -0
- package/dist/src/interview/questions.js.map +1 -0
- package/dist/src/interview/repository.d.ts +25 -0
- package/dist/src/interview/repository.d.ts.map +1 -0
- package/dist/src/interview/repository.js +102 -0
- package/dist/src/interview/repository.js.map +1 -0
- package/dist/src/interview/session.d.ts +22 -0
- package/dist/src/interview/session.d.ts.map +1 -0
- package/dist/src/interview/session.js +120 -0
- package/dist/src/interview/session.js.map +1 -0
- package/dist/src/llm/adapter.d.ts +8 -0
- package/dist/src/llm/adapter.d.ts.map +1 -0
- package/dist/src/llm/adapter.js +42 -0
- package/dist/src/llm/adapter.js.map +1 -0
- package/dist/src/llm/openai-adapter.d.ts +8 -0
- package/dist/src/llm/openai-adapter.d.ts.map +1 -0
- package/dist/src/llm/openai-adapter.js +45 -0
- package/dist/src/llm/openai-adapter.js.map +1 -0
- package/dist/src/llm/prompts.d.ts +15 -0
- package/dist/src/llm/prompts.d.ts.map +1 -0
- package/dist/src/llm/prompts.js +83 -0
- package/dist/src/llm/prompts.js.map +1 -0
- package/dist/src/llm/types.d.ts +21 -0
- package/dist/src/llm/types.d.ts.map +1 -0
- package/dist/src/llm/types.js +2 -0
- package/dist/src/llm/types.js.map +1 -0
- package/dist/src/mcp/schemas.d.ts +799 -0
- package/dist/src/mcp/schemas.d.ts.map +1 -0
- package/dist/src/mcp/schemas.js +151 -0
- package/dist/src/mcp/schemas.js.map +1 -0
- package/dist/src/mcp/server.d.ts +13 -0
- package/dist/src/mcp/server.d.ts.map +1 -0
- package/dist/src/mcp/server.js +255 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/tools/execute-passthrough.d.ts +4 -0
- package/dist/src/mcp/tools/execute-passthrough.d.ts.map +1 -0
- package/dist/src/mcp/tools/execute-passthrough.js +349 -0
- package/dist/src/mcp/tools/execute-passthrough.js.map +1 -0
- package/dist/src/mcp/tools/index.d.ts +4 -0
- package/dist/src/mcp/tools/index.d.ts.map +1 -0
- package/dist/src/mcp/tools/index.js +4 -0
- package/dist/src/mcp/tools/index.js.map +1 -0
- package/dist/src/mcp/tools/interview-passthrough.d.ts +4 -0
- package/dist/src/mcp/tools/interview-passthrough.d.ts.map +1 -0
- package/dist/src/mcp/tools/interview-passthrough.js +96 -0
- package/dist/src/mcp/tools/interview-passthrough.js.map +1 -0
- package/dist/src/mcp/tools/interview.d.ts +4 -0
- package/dist/src/mcp/tools/interview.d.ts.map +1 -0
- package/dist/src/mcp/tools/interview.js +85 -0
- package/dist/src/mcp/tools/interview.js.map +1 -0
- package/dist/src/mcp/tools/seed-passthrough.d.ts +5 -0
- package/dist/src/mcp/tools/seed-passthrough.d.ts.map +1 -0
- package/dist/src/mcp/tools/seed-passthrough.js +29 -0
- package/dist/src/mcp/tools/seed-passthrough.js.map +1 -0
- package/dist/src/mcp/tools/seed.d.ts +5 -0
- package/dist/src/mcp/tools/seed.d.ts.map +1 -0
- package/dist/src/mcp/tools/seed.js +19 -0
- package/dist/src/mcp/tools/seed.js.map +1 -0
- package/dist/src/mcp/tools/spec-passthrough.d.ts +5 -0
- package/dist/src/mcp/tools/spec-passthrough.d.ts.map +1 -0
- package/dist/src/mcp/tools/spec-passthrough.js +29 -0
- package/dist/src/mcp/tools/spec-passthrough.js.map +1 -0
- package/dist/src/mcp/tools/spec.d.ts +5 -0
- package/dist/src/mcp/tools/spec.d.ts.map +1 -0
- package/dist/src/mcp/tools/spec.js +19 -0
- package/dist/src/mcp/tools/spec.js.map +1 -0
- package/dist/src/mcp/tools/status.d.ts +4 -0
- package/dist/src/mcp/tools/status.d.ts.map +1 -0
- package/dist/src/mcp/tools/status.js +45 -0
- package/dist/src/mcp/tools/status.js.map +1 -0
- package/dist/src/registry/base-registry.d.ts +26 -0
- package/dist/src/registry/base-registry.d.ts.map +1 -0
- package/dist/src/registry/base-registry.js +82 -0
- package/dist/src/registry/base-registry.js.map +1 -0
- package/dist/src/seed/extractor.d.ts +15 -0
- package/dist/src/seed/extractor.d.ts.map +1 -0
- package/dist/src/seed/extractor.js +88 -0
- package/dist/src/seed/extractor.js.map +1 -0
- package/dist/src/seed/generator.d.ts +12 -0
- package/dist/src/seed/generator.d.ts.map +1 -0
- package/dist/src/seed/generator.js +66 -0
- package/dist/src/seed/generator.js.map +1 -0
- package/dist/src/seed/passthrough-generator.d.ts +31 -0
- package/dist/src/seed/passthrough-generator.d.ts.map +1 -0
- package/dist/src/seed/passthrough-generator.js +80 -0
- package/dist/src/seed/passthrough-generator.js.map +1 -0
- package/dist/src/seed/schema.d.ts +145 -0
- package/dist/src/seed/schema.d.ts.map +1 -0
- package/dist/src/seed/schema.js +37 -0
- package/dist/src/seed/schema.js.map +1 -0
- package/dist/src/skills/executor.d.ts +14 -0
- package/dist/src/skills/executor.d.ts.map +1 -0
- package/dist/src/skills/executor.js +17 -0
- package/dist/src/skills/executor.js.map +1 -0
- package/dist/src/skills/parser.d.ts +3 -0
- package/dist/src/skills/parser.d.ts.map +1 -0
- package/dist/src/skills/parser.js +37 -0
- package/dist/src/skills/parser.js.map +1 -0
- package/dist/src/skills/registry.d.ts +8 -0
- package/dist/src/skills/registry.d.ts.map +1 -0
- package/dist/src/skills/registry.js +19 -0
- package/dist/src/skills/registry.js.map +1 -0
- package/dist/src/skills/types.d.ts +19 -0
- package/dist/src/skills/types.d.ts.map +1 -0
- package/dist/src/skills/types.js +2 -0
- package/dist/src/skills/types.js.map +1 -0
- package/dist/src/spec/extractor.d.ts +15 -0
- package/dist/src/spec/extractor.d.ts.map +1 -0
- package/dist/src/spec/extractor.js +88 -0
- package/dist/src/spec/extractor.js.map +1 -0
- package/dist/src/spec/generator.d.ts +12 -0
- package/dist/src/spec/generator.d.ts.map +1 -0
- package/dist/src/spec/generator.js +66 -0
- package/dist/src/spec/generator.js.map +1 -0
- package/dist/src/spec/passthrough-generator.d.ts +34 -0
- package/dist/src/spec/passthrough-generator.d.ts.map +1 -0
- package/dist/src/spec/passthrough-generator.js +86 -0
- package/dist/src/spec/passthrough-generator.js.map +1 -0
- package/dist/src/spec/schema.d.ts +145 -0
- package/dist/src/spec/schema.d.ts.map +1 -0
- package/dist/src/spec/schema.js +37 -0
- package/dist/src/spec/schema.js.map +1 -0
- package/package.json +53 -0
- package/skills/execute/SKILL.md +84 -0
- package/skills/interview/SKILL.md +82 -0
- package/skills/spec/SKILL.md +92 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../../src/interview/repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { InterviewSession, InterviewRound, AmbiguityScore, ProjectType, GestaltPrinciple } from '../core/types.js';
|
|
2
|
+
import { EventStore } from '../events/store.js';
|
|
3
|
+
export declare class SessionManager {
|
|
4
|
+
private eventStore;
|
|
5
|
+
private sessions;
|
|
6
|
+
constructor(eventStore: EventStore);
|
|
7
|
+
/**
|
|
8
|
+
* EventStore에서 기존 세션을 복원하여 메모리 Map에 로드한다.
|
|
9
|
+
* 서버 시작 시 한 번 호출.
|
|
10
|
+
*/
|
|
11
|
+
loadFromStore(): void;
|
|
12
|
+
create(topic: string, projectType: ProjectType): InterviewSession;
|
|
13
|
+
get(sessionId: string): InterviewSession;
|
|
14
|
+
getLatest(): InterviewSession | null;
|
|
15
|
+
addQuestion(sessionId: string, question: string, gestaltFocus: GestaltPrinciple): InterviewRound;
|
|
16
|
+
recordResponse(sessionId: string, response: string): InterviewRound;
|
|
17
|
+
updateAmbiguityScore(sessionId: string, score: AmbiguityScore): void;
|
|
18
|
+
complete(sessionId: string): InterviewSession;
|
|
19
|
+
abort(sessionId: string): InterviewSession;
|
|
20
|
+
list(): InterviewSession[];
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/interview/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,WAAW,EACX,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIhD,qBAAa,cAAc;IAGb,OAAO,CAAC,UAAU;IAF9B,OAAO,CAAC,QAAQ,CAAuC;gBAEnC,UAAU,EAAE,UAAU;IAE1C;;;OAGG;IACH,aAAa,IAAI,IAAI;IAQrB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,gBAAgB;IAsBjE,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB;IAMxC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAQpC,WAAW,CACT,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,gBAAgB,GAC7B,cAAc;IA0BjB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc;IAoBnE,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI;IAYpE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB;IAa7C,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB;IAO1C,IAAI,IAAI,gBAAgB,EAAE;CAK3B"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { SessionNotFoundError, SessionAlreadyCompletedError } from '../core/errors.js';
|
|
3
|
+
import { EventType } from '../events/types.js';
|
|
4
|
+
import { InterviewSessionRepository } from './repository.js';
|
|
5
|
+
export class SessionManager {
|
|
6
|
+
eventStore;
|
|
7
|
+
sessions = new Map();
|
|
8
|
+
constructor(eventStore) {
|
|
9
|
+
this.eventStore = eventStore;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* EventStore에서 기존 세션을 복원하여 메모리 Map에 로드한다.
|
|
13
|
+
* 서버 시작 시 한 번 호출.
|
|
14
|
+
*/
|
|
15
|
+
loadFromStore() {
|
|
16
|
+
const repo = new InterviewSessionRepository(this.eventStore);
|
|
17
|
+
const restored = repo.reconstructAll();
|
|
18
|
+
for (const session of restored) {
|
|
19
|
+
this.sessions.set(session.sessionId, session);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
create(topic, projectType) {
|
|
23
|
+
const session = {
|
|
24
|
+
sessionId: randomUUID(),
|
|
25
|
+
topic,
|
|
26
|
+
status: 'in_progress',
|
|
27
|
+
projectType,
|
|
28
|
+
rounds: [],
|
|
29
|
+
ambiguityScore: null,
|
|
30
|
+
createdAt: new Date().toISOString(),
|
|
31
|
+
updatedAt: new Date().toISOString(),
|
|
32
|
+
};
|
|
33
|
+
this.sessions.set(session.sessionId, session);
|
|
34
|
+
this.eventStore.append('interview', session.sessionId, EventType.INTERVIEW_SESSION_STARTED, {
|
|
35
|
+
topic,
|
|
36
|
+
projectType,
|
|
37
|
+
});
|
|
38
|
+
return session;
|
|
39
|
+
}
|
|
40
|
+
get(sessionId) {
|
|
41
|
+
const session = this.sessions.get(sessionId);
|
|
42
|
+
if (!session)
|
|
43
|
+
throw new SessionNotFoundError(sessionId);
|
|
44
|
+
return session;
|
|
45
|
+
}
|
|
46
|
+
getLatest() {
|
|
47
|
+
let latest = null;
|
|
48
|
+
for (const session of this.sessions.values()) {
|
|
49
|
+
latest = session;
|
|
50
|
+
}
|
|
51
|
+
return latest;
|
|
52
|
+
}
|
|
53
|
+
addQuestion(sessionId, question, gestaltFocus) {
|
|
54
|
+
const session = this.get(sessionId);
|
|
55
|
+
if (session.status !== 'in_progress') {
|
|
56
|
+
throw new SessionAlreadyCompletedError(sessionId);
|
|
57
|
+
}
|
|
58
|
+
const round = {
|
|
59
|
+
roundNumber: session.rounds.length + 1,
|
|
60
|
+
question,
|
|
61
|
+
userResponse: null,
|
|
62
|
+
gestaltFocus,
|
|
63
|
+
timestamp: new Date().toISOString(),
|
|
64
|
+
};
|
|
65
|
+
session.rounds.push(round);
|
|
66
|
+
session.updatedAt = new Date().toISOString();
|
|
67
|
+
this.eventStore.append('interview', sessionId, EventType.INTERVIEW_QUESTION_ASKED, {
|
|
68
|
+
roundNumber: round.roundNumber,
|
|
69
|
+
question,
|
|
70
|
+
gestaltFocus,
|
|
71
|
+
});
|
|
72
|
+
return round;
|
|
73
|
+
}
|
|
74
|
+
recordResponse(sessionId, response) {
|
|
75
|
+
const session = this.get(sessionId);
|
|
76
|
+
if (session.status !== 'in_progress') {
|
|
77
|
+
throw new SessionAlreadyCompletedError(sessionId);
|
|
78
|
+
}
|
|
79
|
+
const currentRound = session.rounds[session.rounds.length - 1];
|
|
80
|
+
if (!currentRound)
|
|
81
|
+
throw new SessionNotFoundError(sessionId);
|
|
82
|
+
currentRound.userResponse = response;
|
|
83
|
+
session.updatedAt = new Date().toISOString();
|
|
84
|
+
this.eventStore.append('interview', sessionId, EventType.INTERVIEW_RESPONSE_RECORDED, {
|
|
85
|
+
roundNumber: currentRound.roundNumber,
|
|
86
|
+
response,
|
|
87
|
+
});
|
|
88
|
+
return currentRound;
|
|
89
|
+
}
|
|
90
|
+
updateAmbiguityScore(sessionId, score) {
|
|
91
|
+
const session = this.get(sessionId);
|
|
92
|
+
session.ambiguityScore = score;
|
|
93
|
+
session.updatedAt = new Date().toISOString();
|
|
94
|
+
this.eventStore.append('interview', sessionId, EventType.INTERVIEW_AMBIGUITY_SCORED, {
|
|
95
|
+
overall: score.overall,
|
|
96
|
+
isReady: score.isReady,
|
|
97
|
+
dimensions: score.dimensions,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
complete(sessionId) {
|
|
101
|
+
const session = this.get(sessionId);
|
|
102
|
+
session.status = 'completed';
|
|
103
|
+
session.updatedAt = new Date().toISOString();
|
|
104
|
+
this.eventStore.append('interview', sessionId, EventType.INTERVIEW_SESSION_COMPLETED, {
|
|
105
|
+
totalRounds: session.rounds.length,
|
|
106
|
+
finalAmbiguityScore: session.ambiguityScore?.overall ?? null,
|
|
107
|
+
});
|
|
108
|
+
return session;
|
|
109
|
+
}
|
|
110
|
+
abort(sessionId) {
|
|
111
|
+
const session = this.get(sessionId);
|
|
112
|
+
session.status = 'aborted';
|
|
113
|
+
session.updatedAt = new Date().toISOString();
|
|
114
|
+
return session;
|
|
115
|
+
}
|
|
116
|
+
list() {
|
|
117
|
+
return Array.from(this.sessions.values()).sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/interview/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LLMAdapter, LLMRequest, LLMResponse } from './types.js';
|
|
2
|
+
export declare class AnthropicAdapter implements LLMAdapter {
|
|
3
|
+
private client;
|
|
4
|
+
private model;
|
|
5
|
+
constructor(apiKey: string, model: string);
|
|
6
|
+
chat(request: LLMRequest): Promise<LLMResponse>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/llm/adapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEtE,qBAAa,gBAAiB,YAAW,UAAU;IACjD,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAKnC,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CAgCtD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
import { LLM_TEMPERATURE, LLM_MAX_TOKENS } from '../core/constants.js';
|
|
3
|
+
import { LLMError } from '../core/errors.js';
|
|
4
|
+
export class AnthropicAdapter {
|
|
5
|
+
client;
|
|
6
|
+
model;
|
|
7
|
+
constructor(apiKey, model) {
|
|
8
|
+
this.client = new Anthropic({ apiKey });
|
|
9
|
+
this.model = model;
|
|
10
|
+
}
|
|
11
|
+
async chat(request) {
|
|
12
|
+
try {
|
|
13
|
+
const response = await this.client.messages.create({
|
|
14
|
+
model: this.model,
|
|
15
|
+
max_tokens: request.maxTokens ?? LLM_MAX_TOKENS,
|
|
16
|
+
temperature: request.temperature ?? LLM_TEMPERATURE,
|
|
17
|
+
system: request.system,
|
|
18
|
+
messages: request.messages.map((m) => ({
|
|
19
|
+
role: m.role,
|
|
20
|
+
content: m.content,
|
|
21
|
+
})),
|
|
22
|
+
});
|
|
23
|
+
const textBlock = response.content.find((b) => b.type === 'text');
|
|
24
|
+
if (!textBlock || textBlock.type !== 'text') {
|
|
25
|
+
throw new LLMError('No text content in LLM response');
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
content: textBlock.text,
|
|
29
|
+
usage: {
|
|
30
|
+
inputTokens: response.usage.input_tokens,
|
|
31
|
+
outputTokens: response.usage.output_tokens,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
if (e instanceof LLMError)
|
|
37
|
+
throw e;
|
|
38
|
+
throw new LLMError(`Anthropic API error: ${e instanceof Error ? e.message : String(e)}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/llm/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7C,MAAM,OAAO,gBAAgB;IACnB,MAAM,CAAY;IAClB,KAAK,CAAS;IAEtB,YAAY,MAAc,EAAE,KAAa;QACvC,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAmB;QAC5B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACjD,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU,EAAE,OAAO,CAAC,SAAS,IAAI,cAAc;gBAC/C,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,eAAe;gBACnD,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACrC,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,OAAO,EAAE,CAAC,CAAC,OAAO;iBACnB,CAAC,CAAC;aACJ,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;YAClE,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC5C,MAAM,IAAI,QAAQ,CAAC,iCAAiC,CAAC,CAAC;YACxD,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,SAAS,CAAC,IAAI;gBACvB,KAAK,EAAE;oBACL,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,YAAY;oBACxC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa;iBAC3C;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,YAAY,QAAQ;gBAAE,MAAM,CAAC,CAAC;YACnC,MAAM,IAAI,QAAQ,CAChB,wBAAwB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACrE,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LLMAdapter, LLMRequest, LLMResponse } from './types.js';
|
|
2
|
+
export declare class OpenAIAdapter implements LLMAdapter {
|
|
3
|
+
private client;
|
|
4
|
+
private model;
|
|
5
|
+
constructor(apiKey: string, model: string);
|
|
6
|
+
chat(request: LLMRequest): Promise<LLMResponse>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=openai-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-adapter.d.ts","sourceRoot":"","sources":["../../../src/llm/openai-adapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEtE,qBAAa,aAAc,YAAW,UAAU;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAKnC,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CAsCtD"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import { LLM_TEMPERATURE, LLM_MAX_TOKENS } from '../core/constants.js';
|
|
3
|
+
import { LLMError } from '../core/errors.js';
|
|
4
|
+
export class OpenAIAdapter {
|
|
5
|
+
client;
|
|
6
|
+
model;
|
|
7
|
+
constructor(apiKey, model) {
|
|
8
|
+
this.client = new OpenAI({ apiKey });
|
|
9
|
+
this.model = model;
|
|
10
|
+
}
|
|
11
|
+
async chat(request) {
|
|
12
|
+
try {
|
|
13
|
+
const messages = [];
|
|
14
|
+
if (request.system) {
|
|
15
|
+
messages.push({ role: 'system', content: request.system });
|
|
16
|
+
}
|
|
17
|
+
for (const m of request.messages) {
|
|
18
|
+
messages.push({ role: m.role, content: m.content });
|
|
19
|
+
}
|
|
20
|
+
const response = await this.client.chat.completions.create({
|
|
21
|
+
model: this.model,
|
|
22
|
+
max_tokens: request.maxTokens ?? LLM_MAX_TOKENS,
|
|
23
|
+
temperature: request.temperature ?? LLM_TEMPERATURE,
|
|
24
|
+
messages,
|
|
25
|
+
});
|
|
26
|
+
const choice = response.choices[0];
|
|
27
|
+
if (!choice?.message?.content) {
|
|
28
|
+
throw new LLMError('No content in OpenAI response');
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
content: choice.message.content,
|
|
32
|
+
usage: {
|
|
33
|
+
inputTokens: response.usage?.prompt_tokens ?? 0,
|
|
34
|
+
outputTokens: response.usage?.completion_tokens ?? 0,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
if (e instanceof LLMError)
|
|
40
|
+
throw e;
|
|
41
|
+
throw new LLMError(`OpenAI API error: ${e instanceof Error ? e.message : String(e)}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=openai-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-adapter.js","sourceRoot":"","sources":["../../../src/llm/openai-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7C,MAAM,OAAO,aAAa;IAChB,MAAM,CAAS;IACf,KAAK,CAAS;IAEtB,YAAY,MAAc,EAAE,KAAa;QACvC,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAmB;QAC5B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAwC,EAAE,CAAC;YAEzD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7D,CAAC;YAED,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YACtD,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;gBACzD,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU,EAAE,OAAO,CAAC,SAAS,IAAI,cAAc;gBAC/C,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,eAAe;gBACnD,QAAQ;aACT,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;gBAC9B,MAAM,IAAI,QAAQ,CAAC,+BAA+B,CAAC,CAAC;YACtD,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO;gBAC/B,KAAK,EAAE;oBACL,WAAW,EAAE,QAAQ,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC;oBAC/C,YAAY,EAAE,QAAQ,CAAC,KAAK,EAAE,iBAAiB,IAAI,CAAC;iBACrD;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,YAAY,QAAQ;gBAAE,MAAM,CAAC,CAAC;YACnC,MAAM,IAAI,QAAQ,CAChB,qBAAqB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAClE,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { GestaltPrinciple } from '../core/types.js';
|
|
2
|
+
export declare const INTERVIEW_SYSTEM_PROMPT = "You are a Gestalt-trained requirements analyst. Your goal is to transform vague ideas into crystal-clear specifications by applying Gestalt psychology principles.\n\n## Core Principles\n- **Closure**: Fill in missing requirements \u2014 identify what's implied but unstated\n- **Proximity**: Group related requirements \u2014 find natural clusters\n- **Similarity**: Identify patterns \u2014 spot recurring themes across requirements\n- **Figure-Ground**: Separate essential from optional \u2014 clarify MVP scope\n- **Continuity**: Cross-validate consistency \u2014 detect contradictions\n\n## Rules\n1. Ask ONE focused question at a time\n2. Each question should target a specific Gestalt principle\n3. Build on previous answers \u2014 don't repeat what's already clear\n4. Be conversational but precise\n5. When detecting contradictions (Continuity), address them directly but diplomatically\n6. Always respond in the user's language";
|
|
3
|
+
export declare function buildQuestionPrompt(topic: string, principle: GestaltPrinciple, previousRounds: {
|
|
4
|
+
question: string;
|
|
5
|
+
response: string | null;
|
|
6
|
+
}[], projectType: 'greenfield' | 'brownfield'): string;
|
|
7
|
+
export declare function buildAmbiguityPrompt(topic: string, rounds: {
|
|
8
|
+
question: string;
|
|
9
|
+
response: string | null;
|
|
10
|
+
}[], projectType: 'greenfield' | 'brownfield'): string;
|
|
11
|
+
export declare function buildSpecPrompt(topic: string, rounds: {
|
|
12
|
+
question: string;
|
|
13
|
+
response: string;
|
|
14
|
+
}[], projectType: 'greenfield' | 'brownfield'): string;
|
|
15
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/llm/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,eAAO,MAAM,uBAAuB,66BAeK,CAAC;AAE1C,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,gBAAgB,EAC3B,cAAc,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAAE,EAC/D,WAAW,EAAE,YAAY,GAAG,YAAY,GACvC,MAAM,CAkBR;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAAE,EACvD,WAAW,EAAE,YAAY,GAAG,YAAY,GACvC,MAAM,CAwBR;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAAE,EAChD,WAAW,EAAE,YAAY,GAAG,YAAY,GACvC,MAAM,CAuBR"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { PRINCIPLE_QUESTION_STRATEGIES } from '../core/constants.js';
|
|
2
|
+
export const INTERVIEW_SYSTEM_PROMPT = `You are a Gestalt-trained requirements analyst. Your goal is to transform vague ideas into crystal-clear specifications by applying Gestalt psychology principles.
|
|
3
|
+
|
|
4
|
+
## Core Principles
|
|
5
|
+
- **Closure**: Fill in missing requirements — identify what's implied but unstated
|
|
6
|
+
- **Proximity**: Group related requirements — find natural clusters
|
|
7
|
+
- **Similarity**: Identify patterns — spot recurring themes across requirements
|
|
8
|
+
- **Figure-Ground**: Separate essential from optional — clarify MVP scope
|
|
9
|
+
- **Continuity**: Cross-validate consistency — detect contradictions
|
|
10
|
+
|
|
11
|
+
## Rules
|
|
12
|
+
1. Ask ONE focused question at a time
|
|
13
|
+
2. Each question should target a specific Gestalt principle
|
|
14
|
+
3. Build on previous answers — don't repeat what's already clear
|
|
15
|
+
4. Be conversational but precise
|
|
16
|
+
5. When detecting contradictions (Continuity), address them directly but diplomatically
|
|
17
|
+
6. Always respond in the user's language`;
|
|
18
|
+
export function buildQuestionPrompt(topic, principle, previousRounds, projectType) {
|
|
19
|
+
const strategy = PRINCIPLE_QUESTION_STRATEGIES[principle];
|
|
20
|
+
const history = previousRounds
|
|
21
|
+
.map((r, i) => `Round ${i + 1}:\nQ: ${r.question}\nA: ${r.response ?? '(no response)'}`)
|
|
22
|
+
.join('\n\n');
|
|
23
|
+
return `Topic: "${topic}"
|
|
24
|
+
Project type: ${projectType}
|
|
25
|
+
Current Gestalt focus: ${principle}
|
|
26
|
+
Strategy: ${strategy}
|
|
27
|
+
|
|
28
|
+
${history ? `Previous rounds:\n${history}\n\n` : ''}Generate the next interview question. Apply the ${principle} principle.
|
|
29
|
+
|
|
30
|
+
Respond with ONLY a JSON object:
|
|
31
|
+
{
|
|
32
|
+
"question": "Your question here",
|
|
33
|
+
"reasoning": "Brief explanation of why this question matters for ${principle}"
|
|
34
|
+
}`;
|
|
35
|
+
}
|
|
36
|
+
export function buildAmbiguityPrompt(topic, rounds, projectType) {
|
|
37
|
+
const history = rounds
|
|
38
|
+
.filter((r) => r.response)
|
|
39
|
+
.map((r, i) => `Q${i + 1}: ${r.question}\nA${i + 1}: ${r.response}`)
|
|
40
|
+
.join('\n\n');
|
|
41
|
+
return `Analyze the clarity of this interview for: "${topic}" (${projectType} project)
|
|
42
|
+
|
|
43
|
+
Interview transcript:
|
|
44
|
+
${history}
|
|
45
|
+
|
|
46
|
+
Score each dimension from 0.0 (completely ambiguous) to 1.0 (crystal clear).
|
|
47
|
+
Also detect any contradictions between answers.
|
|
48
|
+
|
|
49
|
+
Respond with ONLY a JSON object:
|
|
50
|
+
{
|
|
51
|
+
"goalClarity": 0.0-1.0,
|
|
52
|
+
"constraintClarity": 0.0-1.0,
|
|
53
|
+
"successCriteria": 0.0-1.0,
|
|
54
|
+
"priorityClarity": 0.0-1.0,
|
|
55
|
+
${projectType === 'brownfield' ? '"contextClarity": 0.0-1.0,' : ''}
|
|
56
|
+
"contradictions": [],
|
|
57
|
+
"reasoning": "Brief analysis"
|
|
58
|
+
}`;
|
|
59
|
+
}
|
|
60
|
+
export function buildSpecPrompt(topic, rounds, projectType) {
|
|
61
|
+
const history = rounds
|
|
62
|
+
.map((r, i) => `Q${i + 1}: ${r.question}\nA${i + 1}: ${r.response}`)
|
|
63
|
+
.join('\n\n');
|
|
64
|
+
return `Generate a complete project specification (Spec) from this interview about: "${topic}" (${projectType} project)
|
|
65
|
+
|
|
66
|
+
Interview transcript:
|
|
67
|
+
${history}
|
|
68
|
+
|
|
69
|
+
Respond with ONLY a JSON object:
|
|
70
|
+
{
|
|
71
|
+
"goal": "Clear, concise project goal",
|
|
72
|
+
"constraints": ["constraint 1", "constraint 2", ...],
|
|
73
|
+
"acceptanceCriteria": ["criterion 1", "criterion 2", ...],
|
|
74
|
+
"ontologySchema": {
|
|
75
|
+
"entities": [{"name": "EntityName", "description": "what it is", "attributes": ["attr1", "attr2"]}],
|
|
76
|
+
"relations": [{"from": "Entity1", "to": "Entity2", "type": "relationship_type"}]
|
|
77
|
+
},
|
|
78
|
+
"gestaltAnalysis": [
|
|
79
|
+
{"principle": "closure|proximity|similarity|figure_ground|continuity", "finding": "what was discovered", "confidence": 0.0-1.0}
|
|
80
|
+
]
|
|
81
|
+
}`;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/llm/prompts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AAErE,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;yCAeE,CAAC;AAE1C,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,SAA2B,EAC3B,cAA+D,EAC/D,WAAwC;IAExC,MAAM,QAAQ,GAAG,6BAA6B,CAAC,SAAS,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,cAAc;SAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,QAAQ,CAAC,CAAC,QAAQ,IAAI,eAAe,EAAE,CAAC;SACvF,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO,WAAW,KAAK;gBACT,WAAW;yBACF,SAAS;YACtB,QAAQ;;EAElB,OAAO,CAAC,CAAC,CAAC,qBAAqB,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,mDAAmD,SAAS;;;;;qEAK1C,SAAS;EAC5E,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAAa,EACb,MAAuD,EACvD,WAAwC;IAExC,MAAM,OAAO,GAAG,MAAM;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;SACzB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;SACnE,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO,+CAA+C,KAAK,MAAM,WAAW;;;EAG5E,OAAO;;;;;;;;;;;IAWL,WAAW,KAAK,YAAY,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,EAAE;;;EAGlE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,MAAgD,EAChD,WAAwC;IAExC,MAAM,OAAO,GAAG,MAAM;SACnB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;SACnE,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO,gFAAgF,KAAK,MAAM,WAAW;;;EAG7G,OAAO;;;;;;;;;;;;;;EAcP,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface LLMMessage {
|
|
2
|
+
role: 'user' | 'assistant';
|
|
3
|
+
content: string;
|
|
4
|
+
}
|
|
5
|
+
export interface LLMRequest {
|
|
6
|
+
system: string;
|
|
7
|
+
messages: LLMMessage[];
|
|
8
|
+
maxTokens?: number;
|
|
9
|
+
temperature?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface LLMResponse {
|
|
12
|
+
content: string;
|
|
13
|
+
usage: {
|
|
14
|
+
inputTokens: number;
|
|
15
|
+
outputTokens: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export interface LLMAdapter {
|
|
19
|
+
chat(request: LLMRequest): Promise<LLMResponse>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/llm/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACjD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/llm/types.ts"],"names":[],"mappings":""}
|