-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
00b619b
commit 8b0ffff
Showing
22 changed files
with
844 additions
and
212 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Agent Output | ||
|
||
This data structure represent the output of the Agent (e.g. the execution of a graph program). | ||
|
||
`FinishReason`: The different reasons for the end of a program. | ||
|
||
`AgentOuput`: The output returned by the Agent system. | ||
|
||
## Definition | ||
|
||
```python | ||
class FinishReason(str, Enum): | ||
MaxIters = "max_iters" | ||
Finished = "finished" | ||
Error = "error" | ||
|
||
class AgentOutput(BaseModel, dspy.Prediction): | ||
finish_reason: FinishReason = Field(description="The finish reason", default=FinishReason.Finished) | ||
final_answer: str = Field(description="The final answer or error if any", default="") | ||
program_trace: AgentStepList = Field(description="The resulting program trace", default_factory=AgentStepList) | ||
session: InteractionSession = Field(description="The resulting interaction session", default_factory=InteractionSession) | ||
|
||
def __init__(self, **kwargs): | ||
BaseModel.__init__(self, **kwargs) | ||
dspy.Prediction.__init__(self, **kwargs) | ||
``` |
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,64 @@ | ||
# Agent State | ||
|
||
This data structure represent the state of the Agent, which contains a stack allowing the agent to jump to other programs by calling them. | ||
|
||
`ProgramState`: Represents the state of an executed program. | ||
|
||
`AgentState`: Represents the state of the agent. | ||
|
||
## Definition | ||
|
||
```python | ||
|
||
class ProgramState(BaseModel): | ||
current_program: GraphProgram = Field(description="The current program") | ||
current_step: Union[Control, Action, Decision, Program] = Field(description="The current step") | ||
|
||
class AgentState(BaseModel): | ||
current_hop: int = Field(description="The current hop", default=0) | ||
decision_hop: int = Field(description="The current decision hop", default=0) | ||
program_trace: AgentStepList = Field(description="The program trace", default_factory=AgentStepList) | ||
program_stack: Iterable[ProgramState] = Field(description="The program stack", default=deque()) | ||
objective: Query = Field(description="The user objective query", default_factory=Query) | ||
final_answer: str = Field(description="The agent final answer", default="") | ||
variables: Dict[str, Any] = Field(description="The variables of the program", default={}) | ||
session: InteractionSession = Field(description="The current interaction session", default_factory=InteractionSession) | ||
|
||
def get_current_state(self) -> Optional[ProgramState]: | ||
"""Method to get the current program state""" | ||
if len(self.program_stack) > 0: | ||
return self.program_stack[-1] | ||
return None | ||
|
||
def get_current_program(self) -> Optional[GraphProgram]: | ||
"""Method to retreive the current program from the stack""" | ||
if len(self.program_stack) > 0: | ||
return self.program_stack[-1].current_program | ||
return None | ||
|
||
def get_current_step(self) -> Optional[Union[Control, Action, Decision, Program]]: | ||
"""Method to retreive the current node from the stack""" | ||
if len(self.program_stack) > 0: | ||
return self.program_stack[-1].current_step | ||
return None | ||
|
||
def set_current_step(self, step: Union[Control, Action, Decision, Program]): | ||
"""Method to set the current node from the stack""" | ||
if len(self.program_stack) > 0: | ||
self.program_stack[-1].current_step = step | ||
else: | ||
raise ValueError("Cannot set the current step when program finished") | ||
|
||
def call_program(self, program: GraphProgram): | ||
"""Method to call a program""" | ||
self.program_stack.append( | ||
ProgramState( | ||
current_program = program, | ||
current_step = program.get_starting_step(), | ||
) | ||
) | ||
|
||
def end_program(self): | ||
"""Method to end the current program (pop the stack)""" | ||
self.program_stack.pop() | ||
``` |
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,100 @@ | ||
# Agent Step | ||
|
||
Here is represented the datastructure used by the Agent System, usually you don't have to worry about it because it is handled automatically by the system. But for documentation purpose, here are the definition of the corresponding structure. | ||
|
||
`AgentStep`: Represents a step performed by the Agent to be stored into memory. | ||
|
||
`AgentStepList`: Represents a list of steps performed by the Agent. | ||
|
||
`QueryWithSteps`: Represents a query associated with a ste list used by the action retrivers and rerankers. | ||
|
||
## Definition | ||
|
||
```python | ||
|
||
class AgentStepType(str, Enum): | ||
Action = "Action" | ||
Decision = "Decision" | ||
ProgramCall = "ProgramCall" | ||
ProgramEnd = "ProgramEnd" | ||
|
||
ACTION_TEMPLATE = \ | ||
"""--- Step {hop} --- | ||
Action Purpose: {purpose} | ||
Action: {prediction}""" | ||
|
||
DECISION_TEMPLATE = \ | ||
"""--- Step {hop} --- | ||
Decision Purpose: {purpose} | ||
Decision: {choice}""" | ||
|
||
CALL_PROGRAM_TEMPLATE = \ | ||
"""--- Step {hop} --- | ||
Call Program: {program} | ||
Program Purpose: {purpose}""" | ||
|
||
END_PROGRAM_TEMPLATE = \ | ||
"""--- Step {hop} --- | ||
End Program: {program}""" | ||
|
||
class AgentStep(BaseModel): | ||
id: Union[UUID, str] = Field(description="Unique identifier for a step", default_factory=uuid4) | ||
parent_id: Optional[Union[UUID, str]] = Field(description="The previous step id if any", default=None) | ||
hop: int = Field(description="The step hop", default=0) | ||
step_type: AgentStepType = Field(description="The step type") | ||
inputs: Optional[Dict[str, Any]] = Field(description="The inputs of the step", default=None) | ||
outputs: Optional[Dict[str, Any]] = Field(description="The outputs of the step", default=None) | ||
vector: Optional[List[float]] = Field(description="Vector representation of the step", default=None) | ||
metadata: Optional[Dict[str, Any]] = Field(description="Additional information about the step", default=None) | ||
created_at: datetime = Field(description="Time when the step was created", default_factory=datetime.now) | ||
|
||
def __str__(self): | ||
if self.inputs is None: | ||
self.inputs = {} | ||
|
||
if self.step_type == AgentStepType.Action: | ||
return ACTION_TEMPLATE.format( | ||
hop=self.hop, | ||
purpose=self.inputs.get("purpose", ""), | ||
prediction=json.dumps(self.outputs, indent=2), | ||
) | ||
elif self.step_type == AgentStepType.Decision: | ||
return DECISION_TEMPLATE.format( | ||
hop=self.hop, | ||
purpose=self.inputs.get("purpose", ""), | ||
choice=self.outputs.get("choice", ""), | ||
) | ||
elif self.step_type == AgentStepType.ProgramCall: | ||
return CALL_PROGRAM_TEMPLATE.format( | ||
hop=self.hop, | ||
purpose=self.inputs.get("purpose", ""), | ||
program=self.inputs.get("program", ""), | ||
) | ||
elif self.step_type == AgentStepType.ProgramEnd: | ||
return END_PROGRAM_TEMPLATE.format( | ||
hop=self.hop, | ||
program=self.inputs.get("program", ""), | ||
) | ||
else: | ||
raise ValueError("Invalid type for AgentStep") | ||
|
||
def to_dict(self): | ||
return {"step": str(self)} | ||
|
||
class AgentStepList(BaseModel, dspy.Prediction): | ||
steps: List[AgentStep] = Field(description="List of agent steps", default=[]) | ||
|
||
def __init__(self, **kwargs): | ||
BaseModel.__init__(self, **kwargs) | ||
dspy.Prediction.__init__(self, **kwargs) | ||
|
||
def to_dict(self): | ||
return {"steps": [s.to_dict() for s in self.steps]} | ||
|
||
class QueryWithSteps(BaseModel, dspy.Prediction): | ||
queries: QueryList = Field(description="The input query list", default_factory=QueryList) | ||
steps: List[AgentStep] = Field(description="List of agent steps", default=[]) | ||
|
||
def to_dict(self): | ||
return {"queries": [q.query for q in self.queries.queries], "steps": [s.to_dict() for s in self.steps]} | ||
``` |
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
Oops, something went wrong.