mirror of
https://github.com/Kaelio/ktx.git
synced 2026-07-01 08:59:39 +02:00
Initial open-source release
This commit is contained in:
commit
1a42152e6f
1199 changed files with 257054 additions and 0 deletions
154
packages/context/src/sl/tools/base-semantic-layer.tool.ts
Normal file
154
packages/context/src/sl/tools/base-semantic-layer.tool.ts
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
import type { ZodType } from 'zod';
|
||||
import type { GitAuthorResolverPort, ToolContext, ToolOutput } from '../../tools/index.js';
|
||||
import { BaseTool } from '../../tools/index.js';
|
||||
import { sourceDefinitionSchema } from '../schemas.js';
|
||||
import { SemanticLayerService } from '../semantic-layer.service.js';
|
||||
import { SlSearchService } from '../sl-search.service.js';
|
||||
|
||||
export { sourceDefinitionSchema };
|
||||
|
||||
// ── Shared output types ──
|
||||
|
||||
export interface SemanticLayerStructured {
|
||||
success: boolean;
|
||||
sourceName: string;
|
||||
yaml?: string;
|
||||
commitHash?: string;
|
||||
errors?: string[];
|
||||
validationErrors?: string[];
|
||||
validationWarnings?: string[];
|
||||
actionRequiredWarnings?: string[];
|
||||
}
|
||||
|
||||
export interface BaseSemanticLayerToolDeps {
|
||||
semanticLayerService: SemanticLayerService;
|
||||
slSearchService: SlSearchService;
|
||||
authorResolver: GitAuthorResolverPort;
|
||||
}
|
||||
|
||||
// ── Abstract base class ──
|
||||
|
||||
export abstract class BaseSemanticLayerTool<TInput extends ZodType = ZodType> extends BaseTool<TInput> {
|
||||
protected readonly semanticLayerService: SemanticLayerService;
|
||||
protected readonly slSearchService: SlSearchService;
|
||||
protected readonly authorResolver: GitAuthorResolverPort;
|
||||
|
||||
constructor(deps: BaseSemanticLayerToolDeps) {
|
||||
super();
|
||||
this.semanticLayerService = deps.semanticLayerService;
|
||||
this.slSearchService = deps.slSearchService;
|
||||
this.authorResolver = deps.authorResolver;
|
||||
}
|
||||
|
||||
protected async readSourceYaml(
|
||||
connectionId: string,
|
||||
sourceName: string,
|
||||
context?: ToolContext,
|
||||
): Promise<string | null> {
|
||||
const semanticLayerService = context?.session?.semanticLayerService ?? this.semanticLayerService;
|
||||
|
||||
try {
|
||||
const { content } = await semanticLayerService.readSourceFile(connectionId, sourceName);
|
||||
return content;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected buildMarkdown(
|
||||
success: boolean,
|
||||
errors: string[],
|
||||
sourceName: string,
|
||||
extra?: {
|
||||
yaml?: string;
|
||||
commitHash?: string;
|
||||
validationErrors?: string[];
|
||||
validationWarnings?: string[];
|
||||
actionRequiredWarnings?: string[];
|
||||
editCount?: number;
|
||||
},
|
||||
): string {
|
||||
const parts: string[] = [];
|
||||
|
||||
if (success) {
|
||||
const verb = extra?.editCount != null ? `applied ${extra.editCount} edit(s) to` : 'saved';
|
||||
parts.push(`Source **${sourceName}** ${verb} successfully.`);
|
||||
} else {
|
||||
parts.push(`Source **${sourceName}** update completed with ${errors.length} error(s):`);
|
||||
for (const err of errors) {
|
||||
parts.push(`- ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (extra?.commitHash) {
|
||||
parts.push(`Commit: \`${extra.commitHash}\``);
|
||||
}
|
||||
|
||||
if (extra?.actionRequiredWarnings && extra.actionRequiredWarnings.length > 0) {
|
||||
parts.push('\n**Action required:**');
|
||||
for (const warning of extra.actionRequiredWarnings) {
|
||||
parts.push(`- ${warning}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (extra?.validationErrors && extra.validationErrors.length > 0) {
|
||||
parts.push('\n**Validation errors:**');
|
||||
for (const ve of extra.validationErrors) {
|
||||
parts.push(`- ${ve}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (extra?.validationWarnings && extra.validationWarnings.length > 0) {
|
||||
parts.push('\n**Validation warnings:**');
|
||||
for (const vw of extra.validationWarnings) {
|
||||
parts.push(`- ${vw}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (extra?.yaml) {
|
||||
const yaml = extra.yaml;
|
||||
const MAX_YAML = 2000;
|
||||
if (yaml.length > MAX_YAML) {
|
||||
parts.push(`\n**YAML** (${yaml.length} chars, truncated):\n\`\`\`yaml\n${yaml.slice(0, MAX_YAML)}...\n\`\`\``);
|
||||
} else {
|
||||
parts.push(`\n**YAML**:\n\`\`\`yaml\n${yaml}\n\`\`\``);
|
||||
}
|
||||
}
|
||||
|
||||
return parts.join('\n');
|
||||
}
|
||||
|
||||
protected buildOutput(
|
||||
success: boolean,
|
||||
errors: string[],
|
||||
sourceName: string,
|
||||
extra?: {
|
||||
yaml?: string;
|
||||
commitHash?: string;
|
||||
validationErrors?: string[];
|
||||
validationWarnings?: string[];
|
||||
actionRequiredWarnings?: string[];
|
||||
editCount?: number;
|
||||
},
|
||||
): ToolOutput<SemanticLayerStructured> {
|
||||
return {
|
||||
markdown: this.buildMarkdown(success, errors, sourceName, extra),
|
||||
structured: {
|
||||
success,
|
||||
sourceName,
|
||||
yaml: extra?.yaml,
|
||||
commitHash: extra?.commitHash,
|
||||
...(errors.length > 0 ? { errors } : {}),
|
||||
...(extra?.validationErrors && extra.validationErrors.length > 0
|
||||
? { validationErrors: extra.validationErrors }
|
||||
: {}),
|
||||
...(extra?.validationWarnings && extra.validationWarnings.length > 0
|
||||
? { validationWarnings: extra.validationWarnings }
|
||||
: {}),
|
||||
...(extra?.actionRequiredWarnings && extra.actionRequiredWarnings.length > 0
|
||||
? { actionRequiredWarnings: extra.actionRequiredWarnings }
|
||||
: {}),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue