feat(server): refactor provider interface (#11665)

fix AI-4
fix AI-18

better provider/model choose to allow fallback to similar models (e.g., self-hosted) when the provider is not fully configured
split functions of different output types
This commit is contained in:
darkskygit
2025-05-22 06:28:20 +00:00
parent a3b8aaff61
commit b388f92c96
36 changed files with 1465 additions and 903 deletions
@@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common';
import { ChatPrompt, PromptService } from '../../prompt';
import {
CopilotChatOptions,
CopilotImageProvider,
CopilotProvider,
CopilotProviderFactory,
} from '../../providers';
import { WorkflowNodeData, WorkflowNodeType } from '../types';
@@ -25,7 +25,7 @@ export class CopilotChatImageExecutor extends AutoRegisteredWorkflowExecutor {
[
WorkflowNodeData & { nodeType: WorkflowNodeType.Basic },
ChatPrompt,
CopilotImageProvider,
CopilotProvider,
]
> {
if (data.nodeType !== WorkflowNodeType.Basic) {
@@ -48,7 +48,7 @@ export class CopilotChatImageExecutor extends AutoRegisteredWorkflowExecutor {
const provider = await this.providerFactory.getProviderByModel(
prompt.model
);
if (provider && 'generateImages' in provider) {
if (provider && 'streamImages' in provider) {
return [data, prompt, provider];
}
@@ -71,25 +71,26 @@ export class CopilotChatImageExecutor extends AutoRegisteredWorkflowExecutor {
const finalMessage = prompt.finish(params);
const config = { ...prompt.config, ...options };
const stream = provider.streamImages(
{ modelId: prompt.model },
finalMessage,
config
);
if (paramKey) {
// update params with custom key
const result = {
[paramKey]: await provider.generateImages(
finalMessage,
prompt.model,
config
),
};
const params = [];
for await (const attachment of stream) {
params.push(attachment);
}
const result = { [paramKey]: params };
yield {
type: NodeExecuteState.Params,
params: paramToucher?.(result) ?? result,
};
} else {
for await (const attachment of provider.generateImagesStream(
finalMessage,
prompt.model,
config
)) {
for await (const attachment of stream) {
yield { type: NodeExecuteState.Attachment, nodeId: id, attachment };
}
}
@@ -3,8 +3,8 @@ import { Injectable } from '@nestjs/common';
import { ChatPrompt, PromptService } from '../../prompt';
import {
CopilotChatOptions,
CopilotProvider,
CopilotProviderFactory,
CopilotTextProvider,
} from '../../providers';
import { WorkflowNodeData, WorkflowNodeType } from '../types';
import { NodeExecuteResult, NodeExecuteState, NodeExecutorType } from './types';
@@ -25,7 +25,7 @@ export class CopilotChatTextExecutor extends AutoRegisteredWorkflowExecutor {
[
WorkflowNodeData & { nodeType: WorkflowNodeType.Basic },
ChatPrompt,
CopilotTextProvider,
CopilotProvider,
]
> {
if (data.nodeType !== WorkflowNodeType.Basic) {
@@ -48,7 +48,7 @@ export class CopilotChatTextExecutor extends AutoRegisteredWorkflowExecutor {
const provider = await this.providerFactory.getProviderByModel(
prompt.model
);
if (provider && 'generateText' in provider) {
if (provider && 'text' in provider) {
return [data, prompt, provider];
}
@@ -74,9 +74,9 @@ export class CopilotChatTextExecutor extends AutoRegisteredWorkflowExecutor {
if (paramKey) {
// update params with custom key
const result = {
[paramKey]: await provider.generateText(
[paramKey]: await provider.text(
{ modelId: prompt.model },
finalMessage,
prompt.model,
config
),
};
@@ -85,9 +85,9 @@ export class CopilotChatTextExecutor extends AutoRegisteredWorkflowExecutor {
params: paramToucher?.(result) ?? result,
};
} else {
for await (const content of provider.generateTextStream(
for await (const content of provider.streamText(
{ modelId: prompt.model },
finalMessage,
prompt.model,
config
)) {
yield { type: NodeExecuteState.Content, nodeId: id, content };