feat(core): add session metadata support (#23068)
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
This commit is contained in:
@@ -79,6 +79,7 @@ export function toPartialRow(info: DeepPartial<Session.Info>) {
|
||||
summary_deletions: grab(info, "summary", (v) => grab(v, "deletions")),
|
||||
summary_files: grab(info, "summary", (v) => grab(v, "files")),
|
||||
summary_diffs: grab(info, "summary", (v) => grab(v, "diffs")),
|
||||
metadata: grab(info, "metadata"),
|
||||
cost: grab(info, "cost"),
|
||||
tokens_input: grab(info, "tokens", (v) => grab(v, "input")),
|
||||
tokens_output: grab(info, "tokens", (v) => grab(v, "output")),
|
||||
|
||||
@@ -33,6 +33,7 @@ export const SessionTable = sqliteTable(
|
||||
summary_deletions: integer(),
|
||||
summary_files: integer(),
|
||||
summary_diffs: text({ mode: "json" }).$type<Snapshot.FileDiff[]>(),
|
||||
metadata: text({ mode: "json" }).$type<Record<string, unknown>>(),
|
||||
cost: real().notNull().default(0),
|
||||
tokens_input: integer().notNull().default(0),
|
||||
tokens_output: integer().notNull().default(0),
|
||||
|
||||
@@ -100,6 +100,7 @@ export function fromRow(row: SessionRow): Info {
|
||||
},
|
||||
},
|
||||
share,
|
||||
metadata: row.metadata ?? undefined,
|
||||
revert,
|
||||
permission: row.permission ? [...row.permission] : undefined,
|
||||
time: {
|
||||
@@ -129,6 +130,7 @@ export function toRow(info: Info) {
|
||||
summary_deletions: info.summary?.deletions,
|
||||
summary_files: info.summary?.files,
|
||||
summary_diffs: info.summary?.diffs,
|
||||
metadata: info.metadata,
|
||||
cost: info.cost ?? 0,
|
||||
tokens_input: (info.tokens ?? EmptyTokens).input,
|
||||
tokens_output: (info.tokens ?? EmptyTokens).output,
|
||||
@@ -205,6 +207,8 @@ const Model = Schema.Struct({
|
||||
variant: optionalOmitUndefined(Schema.String),
|
||||
})
|
||||
|
||||
export const Metadata = Schema.Record(Schema.String, Schema.Any)
|
||||
|
||||
export const Info = Schema.Struct({
|
||||
id: SessionID,
|
||||
slug: Schema.String,
|
||||
@@ -221,6 +225,7 @@ export const Info = Schema.Struct({
|
||||
agent: optionalOmitUndefined(Schema.String),
|
||||
model: optionalOmitUndefined(Model),
|
||||
version: Schema.String,
|
||||
metadata: optionalOmitUndefined(Metadata),
|
||||
time: Time,
|
||||
permission: optionalOmitUndefined(Permission.Ruleset),
|
||||
revert: optionalOmitUndefined(Revert),
|
||||
@@ -246,6 +251,7 @@ export const CreateInput = Schema.optional(
|
||||
title: Schema.optional(Schema.String),
|
||||
agent: Schema.optional(Schema.String),
|
||||
model: Schema.optional(Model),
|
||||
metadata: Schema.optional(Metadata),
|
||||
permission: Schema.optional(Permission.Ruleset),
|
||||
workspaceID: Schema.optional(WorkspaceID),
|
||||
}),
|
||||
@@ -264,6 +270,10 @@ export const SetArchivedInput = Schema.Struct({
|
||||
sessionID: SessionID,
|
||||
time: Schema.optional(ArchivedTimestamp),
|
||||
})
|
||||
export const SetMetadataInput = Schema.Struct({
|
||||
sessionID: SessionID,
|
||||
metadata: Metadata,
|
||||
})
|
||||
export const SetPermissionInput = Schema.Struct({
|
||||
sessionID: SessionID,
|
||||
permission: Permission.Ruleset,
|
||||
@@ -320,6 +330,7 @@ const UpdatedInfo = Schema.Struct({
|
||||
agent: Schema.optional(Schema.NullOr(Schema.String)),
|
||||
model: Schema.optional(Schema.NullOr(Model)),
|
||||
version: Schema.optional(Schema.NullOr(Schema.String)),
|
||||
metadata: Schema.optional(Schema.NullOr(Metadata)),
|
||||
time: Schema.optional(UpdatedTime),
|
||||
permission: Schema.optional(Schema.NullOr(Permission.Ruleset)),
|
||||
revert: Schema.optional(Schema.NullOr(Revert)),
|
||||
@@ -455,6 +466,7 @@ export interface Interface {
|
||||
title?: string
|
||||
agent?: string
|
||||
model?: Schema.Schema.Type<typeof Model>
|
||||
metadata?: typeof Metadata.Type
|
||||
permission?: Permission.Ruleset
|
||||
workspaceID?: WorkspaceID
|
||||
}) => Effect.Effect<Info>
|
||||
@@ -463,6 +475,7 @@ export interface Interface {
|
||||
readonly get: (id: SessionID) => Effect.Effect<Info, NotFound>
|
||||
readonly setTitle: (input: { sessionID: SessionID; title: string }) => Effect.Effect<void>
|
||||
readonly setArchived: (input: { sessionID: SessionID; time?: number }) => Effect.Effect<void>
|
||||
readonly setMetadata: (input: typeof SetMetadataInput.Type) => Effect.Effect<void>
|
||||
readonly setPermission: (input: { sessionID: SessionID; permission: Permission.Ruleset }) => Effect.Effect<void>
|
||||
readonly setRevert: (input: {
|
||||
sessionID: SessionID
|
||||
@@ -529,6 +542,7 @@ export const layer: Layer.Layer<
|
||||
workspaceID?: WorkspaceID
|
||||
directory: string
|
||||
path?: string
|
||||
metadata?: typeof Metadata.Type
|
||||
permission?: Permission.Ruleset
|
||||
}) {
|
||||
const ctx = yield* InstanceState.context
|
||||
@@ -544,6 +558,7 @@ export const layer: Layer.Layer<
|
||||
title: input.title ?? createDefaultTitle(!!input.parentID),
|
||||
agent: input.agent,
|
||||
model: input.model,
|
||||
metadata: input.metadata,
|
||||
permission: input.permission ? [...input.permission] : undefined,
|
||||
cost: 0,
|
||||
tokens: EmptyTokens,
|
||||
@@ -659,6 +674,7 @@ export const layer: Layer.Layer<
|
||||
title?: string
|
||||
agent?: string
|
||||
model?: Schema.Schema.Type<typeof Model>
|
||||
metadata?: typeof Metadata.Type
|
||||
permission?: Permission.Ruleset
|
||||
workspaceID?: WorkspaceID
|
||||
}) {
|
||||
@@ -671,6 +687,7 @@ export const layer: Layer.Layer<
|
||||
title: input?.title,
|
||||
agent: input?.agent,
|
||||
model: input?.model,
|
||||
metadata: input?.metadata,
|
||||
permission: input?.permission,
|
||||
workspaceID: input?.workspaceID ?? workspace,
|
||||
})
|
||||
@@ -685,6 +702,7 @@ export const layer: Layer.Layer<
|
||||
path: sessionPath(ctx.worktree, ctx.directory),
|
||||
workspaceID: original.workspaceID,
|
||||
title,
|
||||
metadata: structuredClone(original.metadata),
|
||||
})
|
||||
const msgs = yield* messages({ sessionID: input.sessionID })
|
||||
const idMap = new Map<string, MessageID>()
|
||||
@@ -732,6 +750,10 @@ export const layer: Layer.Layer<
|
||||
yield* patch(input.sessionID, { time: { archived: input.time } })
|
||||
})
|
||||
|
||||
const setMetadata = Effect.fn("Session.setMetadata")(function* (input: typeof SetMetadataInput.Type) {
|
||||
yield* patch(input.sessionID, { metadata: input.metadata, time: { updated: Date.now() } })
|
||||
})
|
||||
|
||||
const setPermission = Effect.fn("Session.setPermission")(function* (input: {
|
||||
sessionID: SessionID
|
||||
permission: Permission.Ruleset
|
||||
@@ -844,6 +866,7 @@ export const layer: Layer.Layer<
|
||||
get,
|
||||
setTitle,
|
||||
setArchived,
|
||||
setMetadata,
|
||||
setPermission,
|
||||
setRevert,
|
||||
clearRevert,
|
||||
|
||||
Reference in New Issue
Block a user