-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #40 from meta-d/develop
Develop
- Loading branch information
Showing
60 changed files
with
523 additions
and
186 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 86 additions & 39 deletions
125
apps/cloud/src/app/features/project/copilot/architect/graph.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,115 @@ | ||
import { computed, inject } from '@angular/core' | ||
import { END, START, StateGraph, StateGraphArgs } from '@langchain/langgraph/web' | ||
import { CreateGraphOptions } from '@metad/copilot' | ||
import { Plan, injectAgentFewShotTemplate } from '../../../../@core/copilot/' | ||
import { computed, inject, Signal } from '@angular/core' | ||
import { ToolMessage } from '@langchain/core/messages' | ||
import { RunnableLambda } from '@langchain/core/runnables' | ||
import { DynamicStructuredTool } from '@langchain/core/tools' | ||
import { ToolNode } from '@langchain/langgraph/prebuilt' | ||
import { START, StateGraph, StateGraphArgs } from '@langchain/langgraph/web' | ||
import { ChatOpenAI } from '@langchain/openai' | ||
import { Indicator } from '@metad/cloud/state' | ||
import { CreateGraphOptions, Team } from '@metad/copilot' | ||
import { injectDimensionMemberTool } from '@metad/core' | ||
import { ProjectService } from '../../project.service' | ||
import { injectRunIndicatorAgent } from '../indicator/graph' | ||
import { createPlannerAgent } from './agent-planner' | ||
import { createReplannerAgent } from './agent-replanner' | ||
import { | ||
INDICATOR_AGENT_NAME, | ||
IndicatorArchitectCommandName, | ||
IndicatorArchitectState, | ||
PLANNER_NAME, | ||
REPLANNER_NAME | ||
} from './types' | ||
|
||
const superState: StateGraphArgs<IndicatorArchitectState>['channels'] = Plan.createState() | ||
import { promptIndicatorCode } from '../prompt' | ||
import { INDICATOR_AGENT_NAME, IndicatorArchitectState, markdownIndicators } from './types' | ||
|
||
const superState: StateGraphArgs<IndicatorArchitectState>['channels'] = Team.createState() | ||
|
||
export function injectCreateIndicatorArchitect() { | ||
const fewShotTemplate = injectAgentFewShotTemplate(IndicatorArchitectCommandName, { k: 1, vectorStore: null }) | ||
const projectService = inject(ProjectService) | ||
const memberRetrieverTool = injectDimensionMemberTool() | ||
const createIndicatorGraph = injectRunIndicatorAgent() | ||
|
||
const indicators = computed(() => projectService.indicators() ?? []) | ||
|
||
return async ({ llm, checkpointer, interruptBefore, interruptAfter}: CreateGraphOptions) => { | ||
return async ({ llm, checkpointer, interruptBefore, interruptAfter }: CreateGraphOptions) => { | ||
const indicatorWorker = await createIndicatorGraph({ llm }) | ||
|
||
const planner = await createPlannerAgent({ llm, fewShotTemplate, indicators }) | ||
const replanner = await createReplannerAgent({ llm }) | ||
// const planner = await createPlannerAgent({ llm, fewShotTemplate, indicators }) | ||
// const replanner = await createReplannerAgent({ llm }) | ||
const tools = [memberRetrieverTool] | ||
const supervisorAgent = await createSupervisorAgent({ llm, indicators, tools: [] }) | ||
|
||
async function executeStep(state: IndicatorArchitectState): Promise<any> { | ||
const task = state.plan[0] | ||
|
||
const { messages } = await indicatorWorker.invoke({ | ||
messages: [], | ||
role: state.role, | ||
context: state.context, | ||
input: task | ||
input: state.instructions, | ||
}) | ||
|
||
return { | ||
pastSteps: [[task, messages[messages.length - 1].content.toString()]], | ||
plan: state.plan.slice(1), | ||
messages: [messages[messages.length - 1]] | ||
tool_call_id: null, | ||
messages: [ | ||
new ToolMessage({ | ||
tool_call_id: state.tool_call_id, | ||
content: messages[messages.length - 1].content | ||
}) | ||
] | ||
} | ||
} | ||
|
||
function shouldEnd(state: IndicatorArchitectState) { | ||
return state.response ? 'true' : 'false' | ||
} | ||
|
||
const superGraph = new StateGraph({ channels: superState }) | ||
// Add steps nodes | ||
.addNode(PLANNER_NAME, planner) | ||
.addNode(Team.SUPERVISOR_NAME, supervisorAgent.withConfig({ runName: Team.SUPERVISOR_NAME })) | ||
.addNode(Team.TOOLS_NAME, new ToolNode<IndicatorArchitectState>(tools)) | ||
.addNode(INDICATOR_AGENT_NAME, executeStep) | ||
.addNode(REPLANNER_NAME, replanner) | ||
.addEdge(START, PLANNER_NAME) | ||
.addEdge(PLANNER_NAME, INDICATOR_AGENT_NAME) | ||
.addEdge(INDICATOR_AGENT_NAME, REPLANNER_NAME) | ||
.addConditionalEdges(REPLANNER_NAME, shouldEnd, { | ||
true: END, | ||
false: INDICATOR_AGENT_NAME | ||
}) | ||
.addEdge(START, Team.SUPERVISOR_NAME) | ||
.addConditionalEdges(Team.SUPERVISOR_NAME, Team.supervisorRouter) | ||
.addEdge(INDICATOR_AGENT_NAME, Team.SUPERVISOR_NAME) | ||
.addEdge(Team.TOOLS_NAME, Team.SUPERVISOR_NAME) | ||
|
||
return superGraph.compile({ checkpointer, interruptBefore, interruptAfter}) | ||
return superGraph.compile({ checkpointer, interruptBefore, interruptAfter }) | ||
} | ||
} | ||
|
||
export async function createSupervisorAgent({ | ||
llm, | ||
indicators, | ||
tools | ||
}: { | ||
llm: ChatOpenAI | ||
indicators: Signal<Indicator[]> | ||
tools: DynamicStructuredTool[] | ||
}) { | ||
const agent = await Team.createSupervisorAgent( | ||
llm, | ||
[ | ||
{ | ||
name: INDICATOR_AGENT_NAME, | ||
description: 'Create an indicator, only one at a time' | ||
} | ||
], | ||
tools, | ||
`As a indicator system architect specializing in data analysis, your task is to develop a set of indicators specifically for business data analysis based on multidimensional cube information and user prompts, and align with your business role. | ||
Each indicator gives a concise business requirement and name, and the indicators are sorted in the order of creation dependencies. | ||
{role} | ||
{language} | ||
{context} | ||
Methods for indicator design: | ||
- Directly use the basic measures defined in the model, which are measurement data extracted directly from the data source, such as sales amount, inventory quantity, etc. | ||
- Design indicators with calculation formulas, which are indicators calculated based on basic measures, such as year-on-year growth rate, average inventory turnover rate, etc. | ||
- Use Restricted filters to limit measurement data according to specific conditions or dimensions, such as sales in a specific time period, inventory in a certain area, etc. | ||
1. Do not create duplicate indicators that already exist: | ||
{indicators} | ||
2. ${promptIndicatorCode(`{indicatorCodes}`)} | ||
3. Please plan the indicator system first, and then decide to call route to create it one by one. | ||
` | ||
) | ||
|
||
return RunnableLambda.from(async (state: IndicatorArchitectState) => { | ||
return { | ||
...state, | ||
indicators: markdownIndicators(indicators()), | ||
indicatorCodes: indicators() | ||
.map((indicator) => indicator.code) | ||
.join(', '), | ||
} | ||
}).pipe(agent) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export function promptIndicatorCode(indicatorCodes: string) { | ||
return `Indicator code rules: | ||
a. Cannot be the same as the following existing ones: [${indicatorCodes}] | ||
b. Cannot be the same as the name of measures in the cube | ||
c. The code uses a unified coding rule, for example, indicators belonging to the same business module use the same code prefix.` | ||
} |
2 changes: 1 addition & 1 deletion
2
apps/cloud/src/app/features/project/indicators/approvals/approvals.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
apps/cloud/src/app/features/project/indicators/approvals/approvals.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
.../cloud/src/app/features/semantic-model/model/access-control/access-control.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.