-
Notifications
You must be signed in to change notification settings - Fork 68
feat(memory): add read-only event and record commands #1895
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
Changes from all commits
5fb7a8a
85a9196
8dffab9
4043863
ae6a526
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,17 @@ | ||
| import { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NIT - can this be a TS file since it doesn't contain any JSX
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah yes, I was just following the convention in the other files. I can get a follow up PR that fixes it for everything |
||
| GetEventCommand, | ||
| GetMemoryRecordCommand, | ||
| ListEventsCommand, | ||
| ListMemoryRecordsCommand, | ||
| type GetEventInput, | ||
| type GetEventOutput, | ||
| type GetMemoryRecordInput, | ||
| type GetMemoryRecordOutput, | ||
| type ListEventsInput, | ||
| type ListEventsOutput, | ||
| type ListMemoryRecordsInput, | ||
| type ListMemoryRecordsOutput, | ||
| } from "@aws-sdk/client-bedrock-agentcore"; | ||
| import { | ||
| GetMemoryCommand, | ||
| ListMemoriesCommand, | ||
|
|
@@ -27,4 +41,26 @@ export class MemoryClient implements CoreMemoryClient { | |
| .control(toClientConfig(options)) | ||
| .send(new ListMemoriesCommand({ nextToken, maxResults })); | ||
| } | ||
|
|
||
| async getEvent(input: GetEventInput, options: CoreOptions): Promise<GetEventOutput> { | ||
| return this.clients.data(toClientConfig(options)).send(new GetEventCommand(input)); | ||
| } | ||
|
|
||
| async listEvents(input: ListEventsInput, options: CoreOptions): Promise<ListEventsOutput> { | ||
| return this.clients.data(toClientConfig(options)).send(new ListEventsCommand(input)); | ||
| } | ||
|
|
||
| async getMemoryRecord( | ||
| input: GetMemoryRecordInput, | ||
| options: CoreOptions, | ||
| ): Promise<GetMemoryRecordOutput> { | ||
| return this.clients.data(toClientConfig(options)).send(new GetMemoryRecordCommand(input)); | ||
| } | ||
|
|
||
| async listMemoryRecords( | ||
| input: ListMemoryRecordsInput, | ||
| options: CoreOptions, | ||
| ): Promise<ListMemoryRecordsOutput> { | ||
| return this.clients.data(toClientConfig(options)).send(new ListMemoryRecordsCommand(input)); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| import z from "zod"; | ||
| import { InputValidationError } from "../../../../errors"; | ||
| import { createHandler, flag } from "../../../../router"; | ||
| import type { Core } from "../../../types"; | ||
| import { coreOptsFromCtx } from "../../../utils"; | ||
| import { JsonRendererKey } from "../../../../tui"; | ||
|
|
||
| export const createGetMemoryEventHandler = (core: Core) => | ||
| createHandler({ | ||
| name: "get", | ||
| description: "get an AgentCore Memory Event", | ||
| flags: [ | ||
| flag("memory", "the ID of the Memory", z.string().optional()), | ||
| flag("actor-id", "the ID of the actor", z.string().optional()), | ||
| flag("event-id", "the event ID", z.string().optional()), | ||
| flag("session-id", "the session ID", z.string().optional()), | ||
| ], | ||
| handle: async (ctx, flags) => { | ||
| if (!flags.memory) { | ||
| throw new InputValidationError("required option '--memory <memory>' not specified"); | ||
| } | ||
| if (!flags["actor-id"]) { | ||
| throw new InputValidationError("required option '--actor-id <actor-id>' not specified"); | ||
| } | ||
| if (!flags["session-id"]) { | ||
| throw new InputValidationError("required option '--session-id <session-id>' not specified"); | ||
| } | ||
| if (!flags["event-id"]) { | ||
| throw new InputValidationError("required option '--event-id <event-id>' not specified"); | ||
| } | ||
|
|
||
| const response = await core.memory.getEvent( | ||
| { | ||
| memoryId: flags.memory, | ||
| actorId: flags["actor-id"], | ||
| sessionId: flags["session-id"], | ||
| eventId: flags["event-id"], | ||
| }, | ||
| coreOptsFromCtx(ctx), | ||
| ); | ||
|
|
||
| ctx.require(JsonRendererKey).renderJson(response); | ||
| }, | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| import { Router } from "../../../router"; | ||
| import type { Core } from "../../types"; | ||
| import { createGetMemoryEventHandler } from "./get"; | ||
| import { createListMemoryEventsHandler } from "./list"; | ||
|
|
||
| export function createMemoryEventHandler(core: Core): Router { | ||
| return new Router("event", "inspect AgentCore Memory events") | ||
| .handler(createGetMemoryEventHandler(core)) | ||
| .handler(createListMemoryEventsHandler(core)); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| import z from "zod"; | ||
| import { InputValidationError } from "../../../../errors"; | ||
| import { createHandler, flag } from "../../../../router"; | ||
| import type { Core } from "../../../types"; | ||
| import { coreOptsFromCtx } from "../../../utils"; | ||
| import { JsonRendererKey } from "../../../../tui"; | ||
| import { parseEventMetadataFilters } from "../../metadataFilters"; | ||
|
|
||
| export const createListMemoryEventsHandler = (core: Core) => | ||
| createHandler({ | ||
| name: "list", | ||
| description: "list AgentCore Memory events", | ||
| flags: [ | ||
| flag("memory", "the ID of the Memory", z.string().optional()), | ||
| flag("actor-id", "the ID of the actor", z.string().optional()), | ||
| flag("session-id", "the session ID", z.string().optional()), | ||
| flag("include-payloads", "includes event payloads in the response", z.boolean().optional()), | ||
| flag("branch", "filter events by branch name", z.string().optional()), | ||
| flag( | ||
| "include-parent-branches", | ||
| "includes parent branches when filtering by branch", | ||
| z.boolean().optional(), | ||
| ), | ||
| flag("metadata-filters", "event metadata filters as JSON", z.string().optional()), | ||
| flag("max-results", "maximum number of events to return; default 20", z.number().optional()), | ||
| flag("next-token", "pagination token returned by a previous request", z.string().optional()), | ||
| ], | ||
|
|
||
| handle: async (ctx, flags) => { | ||
| if (!flags.memory) { | ||
| throw new InputValidationError("required option '--memory <memory>' not specified"); | ||
| } | ||
| if (!flags["actor-id"]) { | ||
| throw new InputValidationError("required option '--actor-id <actor-id>' not specified"); | ||
| } | ||
| if (!flags["session-id"]) { | ||
| throw new InputValidationError("required option '--session-id <session-id>' not specified"); | ||
| } | ||
|
|
||
| if (flags["include-parent-branches"] && !flags.branch) { | ||
| throw new InputValidationError("'--include-parent-branches' requires '--branch'"); | ||
| } | ||
|
|
||
| const eventMetadata = parseEventMetadataFilters(flags["metadata-filters"]); | ||
| const filter = | ||
| flags.branch || eventMetadata | ||
| ? { | ||
| branch: flags.branch | ||
| ? { | ||
| name: flags.branch, | ||
| includeParentBranches: flags["include-parent-branches"], | ||
| } | ||
| : undefined, | ||
| eventMetadata, | ||
| } | ||
| : undefined; | ||
|
|
||
| const response = await core.memory.listEvents( | ||
| { | ||
| memoryId: flags.memory, | ||
| actorId: flags["actor-id"], | ||
| sessionId: flags["session-id"], | ||
| includePayloads: flags["include-payloads"], | ||
| filter, | ||
| maxResults: flags["max-results"], | ||
| nextToken: flags["next-token"], | ||
| }, | ||
| coreOptsFromCtx(ctx), | ||
| ); | ||
|
|
||
| ctx.require(JsonRendererKey).renderJson(response); | ||
| }, | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The examples include these commands, but the command tree still shows Memory with only get and list. We should add the event and record groups there too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interesting, I thought it did, let me check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be lines 68-70 i believe