Skip to content
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

Add memory agent and caching functionality 🧠✨ #761

Merged
merged 13 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion docs/genaisrc/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/src/components/BuiltinAgents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ import { LinkCard } from '@astrojs/starlight/components';
<LinkCard title="agent git" description="query a repository using Git to accomplish tasks. Provide all the context information available to execute git queries." href="/genaiscript/reference/scripts/system#systemagent_git" />
<LinkCard title="agent github" description="query GitHub to accomplish tasks" href="/genaiscript/reference/scripts/system#systemagent_github" />
<LinkCard title="agent interpreter" description="run code interpreters for Python, Math. Use this agent to ground computation questions." href="/genaiscript/reference/scripts/system#systemagent_interpreter" />
<LinkCard title="agent memory" description="queries the memories created by other agent conversations." href="/genaiscript/reference/scripts/system#systemagent_memory" />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A new agent 'agent memory' has been added to the documentation. Ensure that the description and link are accurate and consistent with the rest of the documentation.

generated by pr-docs-review-commit content_addition

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The newly added LinkCard for "agent memory" should maintain consistency with the other LinkCard entries. Consider adding a period at the end of the description for uniformity.

generated by pr-docs-review-commit content_structure

<LinkCard title="agent user_input" description="ask user for input to confirm, select or answer the question in the query. The message should be very clear and provide all the context." href="/genaiscript/reference/scripts/system#systemagent_user_input" />
12 changes: 12 additions & 0 deletions docs/src/content/docs/reference/scripts/agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,15 @@
```

This full source of this agent is defined in the [system.agent_github](/genaiscript/reference/scripts/system/#systemagent_github) system prompt.

## Agent Memory

The `agent_memory` is a special agent that queries the memories created by other agent conversations. It is used to store and retrieve information from the LLM's memory.

All agent contribute to the conversation memory, and use the `agent_memory`, tool unless it is explicitely disabled using `disableMemory`.

Check notice on line 156 in docs/src/content/docs/reference/scripts/agents.mdx

View workflow job for this annotation

GitHub Actions / build

The word "explicitely" is misspelled; it should be "explicitly".
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The word "explicitely" is misspelled. It should be corrected to "explicitly".

generated by pr-docs-review-commit spelling_error

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The word "explicitely" is misspelled; it should be "explicitly".

generated by pr-docs-review-commit typo


```js "disableMemory: true"
defAgent(..., { disableMemory: true })
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New section 'Agent Memory' added to provide details on the usage and configuration of the 'agent_memory'.

generated by pr-docs-review-commit content_addition

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code snippet provided for disabling memory should be enclosed in a code block for consistency with other code snippets in the documentation.

generated by pr-docs-review-commit code_snippet_format


To enable agent memory in the top level script, add the `agent_memory` tool.
52 changes: 51 additions & 1 deletion docs/src/content/docs/reference/scripts/system.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,7 @@
"github",
"query GitHub to accomplish tasks",
`Your are a helpfull LLM agent that can query GitHub to accomplish tasks. Answer the question in QUERY.
- Prefer diffing job logs rather downloading entire logs which can be very large.

Check failure on line 237 in docs/src/content/docs/reference/scripts/system.mdx

View workflow job for this annotation

GitHub Actions / build

There seems to be a typo here. "ar" should be "are".
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seems to be a typo here. "ar" should be "are".

generated by pr-docs-review-commit typo

- Pull Requests ar a specialized type of issues.
`,
{
model,
Expand Down Expand Up @@ -290,6 +289,57 @@
`````


### `system.agent_memory`

agent that retrieves memories





`````js wrap title="system.agent_memory"
system({
title: "agent that retrieves memories",
})

const cache = await host.cache("memory")
defAgent(
"memory",
"queries the memories created by other agent conversations.",
async (ctx) => {
const memories = await cache.values()
ctx.$`Your are a helpfull LLM agent that acts as a knowledge base for memories created by other agents.
pelikhan marked this conversation as resolved.
Show resolved Hide resolved

Answer the question in QUERY with the memories in MEMORY.

- Use the information in MEMORY exclusively to answer the question in QUERY.
- If the information in MEMORY is not enough to answer the question in QUERY, respond <NO_MEMORY>.
- The memory

Check failure on line 317 in docs/src/content/docs/reference/scripts/system.mdx

View workflow job for this annotation

GitHub Actions / build

The sentence "The memory" is incomplete and does not provide clear information.
pelikhan marked this conversation as resolved.
Show resolved Hide resolved
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a typo in the word "helpfull"; it should be "helpful". Additionally, the sentence "The memory" in line 320 is incomplete and should be revised or removed.

generated by pr-docs-review-commit typo

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The instructions within the code snippet may be unclear due to the incomplete sentence on line 320. This could lead to confusion about the expected behavior of the agent.

generated by pr-docs-review-commit content_clarity

`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sentence "- The memory" is incomplete and seems to be cut off. It should be removed or completed.

generated by pr-docs-review-commit incomplete_sentence

memories.reverse().forEach(
({ agent, query, answer }) =>
ctx.def(
"MEMORY",
`${agent}> ${query}?
${answer}
`
),
{
flex: 1,
}
)
},
{
model: "openai:gpt-4o",
flexTokens: 30000,
system: ["system"],
disableMemory: true,
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A new section for system.agent_memory has been introduced. Ensure that the documentation for this new agent is complete and that the example code provided is correct and functional.

generated by pr-docs-review-commit new_section

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The section for system.agent_memory seems incomplete and lacks proper formatting. It should be structured and formatted consistently with other sections in the document. The placeholder text "agent that retrieves memories" and the repeated empty lines should be addressed for clarity and conciseness.

generated by pr-docs-review-commit document_structure

)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New section 'system.agent_memory' added to describe the agent that retrieves memories.

generated by pr-docs-review-commit content_addition


`````


### `system.agent_user_input`

Agent that can asks questions to the user.
Expand Down
9 changes: 8 additions & 1 deletion eval/extrism/genaisrc/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion genaisrc/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion packages/auto/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/core/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,5 @@ export const CLI_ENV_VAR_RX = /^genaiscript_var_/i

export const GIT_DIFF_MAX_TOKENS = 8000
export const MAX_TOOL_CONTENT_TOKENS = 4000

export const MEMORY_CACHE_NAME = "memory"
9 changes: 8 additions & 1 deletion packages/core/src/genaisrc/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion packages/core/src/genaisrc/system.agent_github.genai.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ defAgent(
"query GitHub to accomplish tasks",
`Your are a helpfull LLM agent that can query GitHub to accomplish tasks. Answer the question in QUERY.
- Prefer diffing job logs rather downloading entire logs which can be very large.
- Pull Requests ar a specialized type of issues.
`,
{
model,
Expand Down
38 changes: 38 additions & 0 deletions packages/core/src/genaisrc/system.agent_memory.genai.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
system({
title: "agent that retrieves memories",
})

const cache = await host.cache("memory")
defAgent(
"memory",
"queries the memories created by other agent conversations.",
async (ctx) => {
const memories = await cache.values()
ctx.$`Your are a helpfull LLM agent that acts as a knowledge base for memories created by other agents.

Answer the question in QUERY with the memories in MEMORY.

- Use the information in MEMORY exclusively to answer the question in QUERY.
- If the information in MEMORY is not enough to answer the question in QUERY, respond <NO_MEMORY>.
- The memory
`
memories.reverse().forEach(
({ agent, query, answer }) =>
ctx.def(
"MEMORY",
`${agent}> ${query}?
${answer}
`
),
{
flex: 1,
}
)
},
{
model: "openai:gpt-4o",
flexTokens: 30000,
system: ["system"],
disableMemory: true,
}
)
34 changes: 31 additions & 3 deletions packages/core/src/runpromptcontext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import { parseModelIdentifier, resolveModelConnectionInfo } from "./models"
import {
CHAT_REQUEST_PER_MODEL_CONCURRENT_LIMIT,
MEMORY_CACHE_NAME,
MODEL_PROVIDER_AICI,
SYSTEM_FENCE,
} from "./constants"
Expand All @@ -59,6 +60,7 @@
import { dedent } from "./indent"
import { runtimeHost } from "./host"
import { writeFileEdits } from "./fileedits"
import { MemoryCache } from "./cache"

export function createChatTurnGenerationContext(
options: GenerationOptions,
Expand Down Expand Up @@ -313,7 +315,8 @@
) => Promise<void>,
options?: DefAgentOptions
): void => {
const { tools, system, ...rest } = options || {}
const { tools, system, disableMemory, ...rest } = options || {}

Check failure on line 318 in packages/core/src/runpromptcontext.ts

View workflow job for this annotation

GitHub Actions / build

The `disableMemory` option in the `options` object is not given a default value. If it is not provided, it will be `undefined` which might lead to unexpected behavior. Consider providing a default value.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The disableMemory option in the options object is not given a default value. If it is not provided in the function call, it will be undefined, which may lead to unexpected behavior.

generated by pr-review-commit missing_default_value

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The disableMemory property is destructured from options but not used in the function. Consider removing it if it's not needed.

generated by pr-review-commit missing_destructuring

const memory = !disableMemory

name = name.replace(/^agent_/i, "")
const agentName = `agent_${name}`
Expand All @@ -327,7 +330,9 @@
const agentTools = resolveTools(
runtimeHost.project,
agentSystem,
arrayify(tools)
[...arrayify(tools), memory ? "agent_memory" : undefined].filter(
(t) => !!t
)

Check failure on line 335 in packages/core/src/runpromptcontext.ts

View workflow job for this annotation

GitHub Actions / build

The filter function `(t) => !!t` is used to remove `undefined` values from the array. However, this might also remove other falsy values like `0`, `''`, `false`, `null`, `NaN`. If these values are valid, consider using a more specific condition in the filter function.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filter function is unnecessary here as the 'undefined' values will not affect the functionality of the 'arrayify' function.

generated by pr-review-commit unnecessary_filter

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filter function (t) => !!t is used to remove undefined values from the array. However, this could also remove other falsy values like 0, '', false, null, NaN, which might be valid in some cases.

generated by pr-review-commit filter_undefined

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expression used to generate the agentTools array is complex and may be difficult to understand. Consider breaking it down into smaller parts for better readability.

generated by pr-review-commit complex_expression

)
const agentDescription = dedent`Agent that uses an LLM to ${description}.\nAvailable tools:
${agentTools.map((t) => `- ${t.description}`).join("\n")}` // DO NOT LEAK TOOL ID HERE
Expand All @@ -347,17 +352,40 @@
},
pelikhan marked this conversation as resolved.
Show resolved Hide resolved
async (args) => {
const { context, query } = args
logVerbose(`${agentLabel}: ${query}`)
context.log(`${agentLabel}: ${query}`)
const res = await runPrompt(
async (_) => {
_.def("QUERY", query)
if (typeof fn === "string") _.writeText(dedent(fn))
else await fn(_, args)
_.$`- Assume that your answer will be analyzed by an LLM, not a human.
${memory ? `- If you are missing information, try querying the memory using 'agent_memory'.` : ""}
- If you are missing information, reply "MISSING_INFO: <what is missing>".
- If you cannot answer the query, return "NO_ANSWER: <reason>".
- Be concise. Minimize output to the most relevant information to save context tokens.
`
if (memory)
_.defOutputProcessor(async ({ text }) => {
const agentMemory = MemoryCache.byName<
{ agent: string; query: string },
{
agent: string
query: string
answer: string
}
>(MEMORY_CACHE_NAME)
const cacheKey = { agent: agentName, query }
const cachedValue = {
...cacheKey,
answer: text,
}
await agentMemory.set(cacheKey, cachedValue)

Check failure on line 382 in packages/core/src/runpromptcontext.ts

View workflow job for this annotation

GitHub Actions / build

The `set` method of `agentMemory` is used without error handling. If an error occurs during the execution of this method, it will not be caught and might lead to unexpected behavior. Consider adding error handling.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The set method of agentMemory is used without error handling. If an error occurs during the execution of this method, it will not be caught and might lead to unexpected behavior. Consider adding error handling.

generated by pr-review-commit missing_error_handling

trace.detailsFenced(
`🧠 memory: ${query}`,
cachedValue.answer,
"markdown"
)
})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no error handling for the async function 'agentMemory.set'. If it fails, it could lead to unexpected behavior.

generated by pr-review-commit missing_error_handling

},
{
label: agentLabel,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/systems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function resolveSystems(
if (/\W(diagram|chart)\W/i.test(jsSource))
systems.push("system.diagrams")

if (/github/i.test(jsSource)) systems.push("system.github_info")
if (/\W(github)\W/i.test(jsSource)) systems.push("system.github_info")
}

// Include tools-related systems if specified in the script
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/types/prompt_template.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2074,7 +2074,12 @@ interface DefToolOptions {
maxTokens?: number
}

interface DefAgentOptions extends Omit<PromptGeneratorOptions, "label"> {}
interface DefAgentOptions extends Omit<PromptGeneratorOptions, "label"> {
/**
* Excludes agent conversation from agent memory
*/
disableMemory?: boolean
}

type ChatAgentHandler = (
ctx: ChatGenerationContext,
Expand Down
Loading
Loading