-
Notifications
You must be signed in to change notification settings - Fork 1
refactor: split optional synthesizer surface out of the core MCP path #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d815a05
27dc0ba
ad8b256
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
devin-ai-integration[bot] marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,4 @@ | ||
| import { getRuntimeLogger } from './logging/runtime-logger.js'; | ||
| import { | ||
| normalizeLmStudioApiStyle, | ||
| runLmStudioHealthCheck, | ||
| } from './runtime/lm-studio-synthesizer.js'; | ||
| import { FpfRuntime } from './runtime/runtime.js'; | ||
| import type { AnswerMode } from './runtime/types.js'; | ||
|
|
||
|
|
@@ -34,9 +30,6 @@ try { | |
| case 'trace': | ||
| await runTrace(args.slice(1)); | ||
| break; | ||
| case 'lm-check': | ||
| await runLmCheck(args.slice(1)); | ||
| break; | ||
| default: | ||
| printHelp(); | ||
| process.exitCode = command === 'help' ? 0 : 1; | ||
|
Comment on lines
33
to
35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Removing the Useful? React with 👍 / 👎.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is intentional — the whole point of this PR (issue #37) is to extract |
||
|
|
@@ -109,24 +102,6 @@ async function runTrace(commandArgs: string[]): Promise<void> { | |
| await print(runtime.trace(question, mode, forceRefresh, sessionId)); | ||
| } | ||
|
|
||
| async function runLmCheck(commandArgs: string[]): Promise<void> { | ||
| const timeoutMsRaw = value(commandArgs, '--timeout-ms'); | ||
| const timeoutMs = timeoutMsRaw ? Number(timeoutMsRaw) : undefined; | ||
| const apiStyle = normalizeLmStudioApiStyle(value(commandArgs, '--api-style')); | ||
|
|
||
| await print( | ||
| runLmStudioHealthCheck({ | ||
| baseUrl: value(commandArgs, '--base-url'), | ||
| model: value(commandArgs, '--model'), | ||
| apiStyle, | ||
| apiKey: value(commandArgs, '--api-key') ?? process.env.FPF_LOCAL_LLM_API_KEY, | ||
| timeoutMs: Number.isFinite(timeoutMs) ? timeoutMs : undefined, | ||
| systemPrompt: value(commandArgs, '--system-prompt'), | ||
| input: value(commandArgs, '--input'), | ||
| }), | ||
| ); | ||
| } | ||
|
|
||
| function flag(argsList: string[], flagName: string): boolean { | ||
| return argsList.includes(flagName); | ||
| } | ||
|
|
@@ -152,6 +127,6 @@ function printHelp(): void { | |
| bun run cli -- inspect --selector "A.1.1" [--kind auto|id|route|lexeme] [--force] | ||
| bun run cli -- read-doc --selector "A.1.1" [--kind auto|id|route|lexeme] [--force] | ||
| bun run cli -- trace --question "How do routes work?" [--mode compact|verbose|proof] [--session s1] [--force] | ||
| bun run cli -- lm-check [--base-url http://localhost:1234/v1] [--model google/gemma-4-31b] [--api-style responses|chat|lmstudio_chat] [--api-key <token>] [--timeout-ms 60000] | ||
| bun run src/runtime/synthesizer/lm-check.ts [--base-url http://localhost:1234/v1] [--model google/gemma-4-31b] [--api-style responses|chat|chat_completions|lmstudio_chat] [--api-key <token>] [--timeout-ms 60000] | ||
| `); | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,15 +1,14 @@ | ||||||||||||||||||||||||
| import { z } from 'zod'; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const answerModeSchema = z.enum(['compact', 'verbose', 'proof']); | ||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||
| answerModeSchema, | ||||||||||||||||||||||||
| answerStatusSchema, | ||||||||||||||||||||||||
| baseQueryInputSchema, | ||||||||||||||||||||||||
| snapshotWithRebuildSchema, | ||||||||||||||||||||||||
| } from './public-contracts.js'; | ||||||||||||||||||||||||
|
Comment on lines
+3
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Import the base query input schema to deduplicate the
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 27dc0ba — |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const nodeKindSchema = z.enum(['pattern', 'route', 'lexeme']); | ||||||||||||||||||||||||
| export const selectorKindSchema = z.enum(['auto', 'id', 'route', 'lexeme']); | ||||||||||||||||||||||||
| export const answerStatusSchema = z.enum([ | ||||||||||||||||||||||||
| 'ok', | ||||||||||||||||||||||||
| 'not_found', | ||||||||||||||||||||||||
| 'ambiguous', | ||||||||||||||||||||||||
| 'unsupported', | ||||||||||||||||||||||||
| 'stale_snapshot_prevented', | ||||||||||||||||||||||||
| ]); | ||||||||||||||||||||||||
| export const anchorRoleSchema = z.enum([ | ||||||||||||||||||||||||
| 'definition', | ||||||||||||||||||||||||
| 'solution', | ||||||||||||||||||||||||
|
|
@@ -26,14 +25,6 @@ export const buildReasonSchema = z.enum([ | |||||||||||||||||||||||
| 'source_hash_changed', | ||||||||||||||||||||||||
| 'snapshot_current', | ||||||||||||||||||||||||
| ]); | ||||||||||||||||||||||||
| export const observabilityFormatSchema = z.enum(['flat', 'tree', 'normalized']); | ||||||||||||||||||||||||
| export const observabilityLogLevelSchema = z.enum([ | ||||||||||||||||||||||||
| 'debug', | ||||||||||||||||||||||||
| 'info', | ||||||||||||||||||||||||
| 'warn', | ||||||||||||||||||||||||
| 'error', | ||||||||||||||||||||||||
| 'fatal', | ||||||||||||||||||||||||
| ]); | ||||||||||||||||||||||||
| export const resolvedAsSchema = z.enum(['id', 'route', 'lexeme', 'not_found']); | ||||||||||||||||||||||||
| export const inspectStatusSchema = z.enum(['ok', 'not_found']); | ||||||||||||||||||||||||
| export const frontierOriginSchema = z.enum([ | ||||||||||||||||||||||||
|
|
@@ -45,15 +36,6 @@ export const frontierOriginSchema = z.enum([ | |||||||||||||||||||||||
| 'session_context', | ||||||||||||||||||||||||
| ]); | ||||||||||||||||||||||||
| export const expandedCitationStatusSchema = z.enum(['ok', 'not_found']); | ||||||||||||||||||||||||
| export const lmStudioApiStyleSchema = z.enum(['responses', 'lmstudio_chat', 'chat_completions']); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const relationEdgeSchema = z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
| from: z.string(), | ||||||||||||||||||||||||
| relation: z.string(), | ||||||||||||||||||||||||
| to: z.string(), | ||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const inspectNeighborSchema = z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
|
|
@@ -110,14 +92,6 @@ export const compiledNodeSchema = z | |||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const snapshotWithRebuildSchema = z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
| sourceHash: z.string(), | ||||||||||||||||||||||||
| builtAt: z.string(), | ||||||||||||||||||||||||
| rebuilt: z.boolean(), | ||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const buildAuditSchema = z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
| sourcePath: z.string(), | ||||||||||||||||||||||||
|
|
@@ -154,78 +128,6 @@ export const buildAuditSchema = z | |||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const queryResultSchema = z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
| mode: answerModeSchema, | ||||||||||||||||||||||||
| question: z.string(), | ||||||||||||||||||||||||
| answer: z.string(), | ||||||||||||||||||||||||
| ids: z.array(z.string()), | ||||||||||||||||||||||||
| relations: z.array(relationEdgeSchema), | ||||||||||||||||||||||||
| constraints: z.array(z.string()), | ||||||||||||||||||||||||
| citations: z.array(z.string()), | ||||||||||||||||||||||||
| confidence: z.number(), | ||||||||||||||||||||||||
| gaps: z.array(z.string()), | ||||||||||||||||||||||||
| snapshot: snapshotWithRebuildSchema, | ||||||||||||||||||||||||
| status: answerStatusSchema, | ||||||||||||||||||||||||
| groundingChain: z.array(z.string()).optional(), | ||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const askFpfResultSchema = z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
| question: z.string(), | ||||||||||||||||||||||||
| mode: answerModeSchema, | ||||||||||||||||||||||||
| markdown: z.string(), | ||||||||||||||||||||||||
| ids: z.array(z.string()), | ||||||||||||||||||||||||
| citations: z.array(z.string()), | ||||||||||||||||||||||||
| constraints: z.array(z.string()), | ||||||||||||||||||||||||
| gaps: z.array(z.string()), | ||||||||||||||||||||||||
| confidence: z.number(), | ||||||||||||||||||||||||
| status: answerStatusSchema, | ||||||||||||||||||||||||
| snapshot: snapshotWithRebuildSchema, | ||||||||||||||||||||||||
| groundingChain: z.array(z.string()).optional(), | ||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const runtimeStatusSchema = z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
| sourcePath: z.string(), | ||||||||||||||||||||||||
| sourceHash: z.string().optional(), | ||||||||||||||||||||||||
| builtAt: z.string().optional(), | ||||||||||||||||||||||||
| snapshotExists: z.boolean(), | ||||||||||||||||||||||||
| currentSourceHash: z.string(), | ||||||||||||||||||||||||
| fresh: z.boolean(), | ||||||||||||||||||||||||
| compilerMode: z.literal('local_vectorless'), | ||||||||||||||||||||||||
| artifacts: z.record(z.string(), z.boolean()), | ||||||||||||||||||||||||
| synthesizer: z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
| configured: z.boolean(), | ||||||||||||||||||||||||
| provider: z.string().optional(), | ||||||||||||||||||||||||
| model: z.string().optional(), | ||||||||||||||||||||||||
| baseUrl: z.string().optional(), | ||||||||||||||||||||||||
| apiStyle: lmStudioApiStyleSchema.optional(), | ||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(), | ||||||||||||||||||||||||
| observability: z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
| configured: z.boolean(), | ||||||||||||||||||||||||
| filePath: z.string(), | ||||||||||||||||||||||||
| format: observabilityFormatSchema, | ||||||||||||||||||||||||
| includeInternalSpans: z.boolean(), | ||||||||||||||||||||||||
| logLevel: observabilityLogLevelSchema, | ||||||||||||||||||||||||
| excludeModelChunks: z.boolean(), | ||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(), | ||||||||||||||||||||||||
| sessionCache: z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
| enabled: z.boolean(), | ||||||||||||||||||||||||
| maxSessions: z.number(), | ||||||||||||||||||||||||
| activeSessions: z.number(), | ||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(), | ||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const traceDetectedSchema = z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
| ids: z.array(z.string()), | ||||||||||||||||||||||||
|
|
@@ -387,25 +289,7 @@ export const refreshFpfIndexInputSchema = z | |||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const queryFpfSpecInputSchema = z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
| question: z.string().min(1), | ||||||||||||||||||||||||
| mode: answerModeSchema.optional(), | ||||||||||||||||||||||||
| forceRefresh: z.boolean().optional(), | ||||||||||||||||||||||||
| sessionId: z.string().min(1).optional(), | ||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const askFpfInputSchema = z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
| question: z.string().min(1), | ||||||||||||||||||||||||
| mode: answerModeSchema.optional(), | ||||||||||||||||||||||||
| forceRefresh: z.boolean().optional(), | ||||||||||||||||||||||||
| sessionId: z.string().min(1).optional(), | ||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const getFpfIndexStatusInputSchema = z.object({}).strict(); | ||||||||||||||||||||||||
| export const traceFpfPathInputSchema = baseQueryInputSchema; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const inspectFpfNodeInputSchema = z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
|
|
@@ -437,19 +321,7 @@ export const expandFpfCitationsInputSchema = z | |||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export const traceFpfPathInputSchema = z | ||||||||||||||||||||||||
| .object({ | ||||||||||||||||||||||||
| question: z.string().min(1), | ||||||||||||||||||||||||
| mode: answerModeSchema.optional(), | ||||||||||||||||||||||||
| forceRefresh: z.boolean().optional(), | ||||||||||||||||||||||||
| sessionId: z.string().min(1).optional(), | ||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| .strict(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export type RefreshFpfIndexInput = z.infer<typeof refreshFpfIndexInputSchema>; | ||||||||||||||||||||||||
| export type QueryFpfSpecInput = z.infer<typeof queryFpfSpecInputSchema>; | ||||||||||||||||||||||||
| export type AskFpfInput = z.infer<typeof askFpfInputSchema>; | ||||||||||||||||||||||||
| export type GetFpfIndexStatusInput = z.infer<typeof getFpfIndexStatusInputSchema>; | ||||||||||||||||||||||||
| export type InspectFpfNodeInput = z.infer<typeof inspectFpfNodeInputSchema>; | ||||||||||||||||||||||||
| export type ReadFpfDocInput = z.infer<typeof readFpfDocInputSchema>; | ||||||||||||||||||||||||
| export type InspectFpfAnchorInput = z.infer<typeof inspectFpfAnchorInputSchema>; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 README documents removed
lm-checkCLI command that no longer existsThe
lm-checksubcommand was removed fromsrc/cli.tsin this PR and replaced by a standalone script atsrc/runtime/synthesizer/lm-check.ts. However, the README still referencesbun run cli -- lm-checkin two separate code blocks (lines 100-101 and 164-165). Users following these instructions will hit thedefaultcase in the CLI switch (src/cli.ts:34-36), which prints help and exits with code 1. The CLI help text atsrc/cli.ts:130was correctly updated to point tobun run src/runtime/synthesizer/lm-check.ts, but the README was not.(Refers to lines 100-101)
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 27dc0ba — updated both README occurrences (lines 100-101 and 164-165) to point to
bun run src/runtime/synthesizer/lm-check.ts.