feat(core): add session metadata support (#23068)
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
This commit is contained in:
co-authored by
Aiden Cline
parent
ac8e686f33
commit
ddc30cd151
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE `session` ADD `metadata` text;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -45,6 +45,7 @@ export const MessagesQuery = Schema.Struct({
|
|||||||
export const StatusMap = Schema.Record(Schema.String, SessionStatus.Info)
|
export const StatusMap = Schema.Record(Schema.String, SessionStatus.Info)
|
||||||
export const UpdatePayload = Schema.Struct({
|
export const UpdatePayload = Schema.Struct({
|
||||||
title: Schema.optional(Schema.String),
|
title: Schema.optional(Schema.String),
|
||||||
|
metadata: Schema.optional(Session.Metadata),
|
||||||
permission: Schema.optional(Permission.Ruleset),
|
permission: Schema.optional(Permission.Ruleset),
|
||||||
time: Schema.optional(
|
time: Schema.optional(
|
||||||
Schema.Struct({
|
Schema.Struct({
|
||||||
|
|||||||
@@ -185,6 +185,9 @@ export const sessionHandlers = HttpApiBuilder.group(InstanceHttpApi, "session",
|
|||||||
if (ctx.payload.title !== undefined) {
|
if (ctx.payload.title !== undefined) {
|
||||||
yield* session.setTitle({ sessionID: ctx.params.sessionID, title: ctx.payload.title })
|
yield* session.setTitle({ sessionID: ctx.params.sessionID, title: ctx.payload.title })
|
||||||
}
|
}
|
||||||
|
if (ctx.payload.metadata !== undefined) {
|
||||||
|
yield* session.setMetadata({ sessionID: ctx.params.sessionID, metadata: ctx.payload.metadata })
|
||||||
|
}
|
||||||
if (ctx.payload.permission !== undefined) {
|
if (ctx.payload.permission !== undefined) {
|
||||||
yield* session.setPermission({
|
yield* session.setPermission({
|
||||||
sessionID: ctx.params.sessionID,
|
sessionID: ctx.params.sessionID,
|
||||||
@@ -202,7 +205,10 @@ export const sessionHandlers = HttpApiBuilder.group(InstanceHttpApi, "session",
|
|||||||
payload?: typeof ForkPayload.Type
|
payload?: typeof ForkPayload.Type
|
||||||
}) {
|
}) {
|
||||||
return yield* SessionError.mapStorageNotFound(
|
return yield* SessionError.mapStorageNotFound(
|
||||||
session.fork({ sessionID: ctx.params.sessionID, messageID: ctx.payload?.messageID }),
|
session.fork({
|
||||||
|
sessionID: ctx.params.sessionID,
|
||||||
|
messageID: ctx.payload?.messageID,
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ export function toPartialRow(info: DeepPartial<Session.Info>) {
|
|||||||
summary_deletions: grab(info, "summary", (v) => grab(v, "deletions")),
|
summary_deletions: grab(info, "summary", (v) => grab(v, "deletions")),
|
||||||
summary_files: grab(info, "summary", (v) => grab(v, "files")),
|
summary_files: grab(info, "summary", (v) => grab(v, "files")),
|
||||||
summary_diffs: grab(info, "summary", (v) => grab(v, "diffs")),
|
summary_diffs: grab(info, "summary", (v) => grab(v, "diffs")),
|
||||||
|
metadata: grab(info, "metadata"),
|
||||||
cost: grab(info, "cost"),
|
cost: grab(info, "cost"),
|
||||||
tokens_input: grab(info, "tokens", (v) => grab(v, "input")),
|
tokens_input: grab(info, "tokens", (v) => grab(v, "input")),
|
||||||
tokens_output: grab(info, "tokens", (v) => grab(v, "output")),
|
tokens_output: grab(info, "tokens", (v) => grab(v, "output")),
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ export const SessionTable = sqliteTable(
|
|||||||
summary_deletions: integer(),
|
summary_deletions: integer(),
|
||||||
summary_files: integer(),
|
summary_files: integer(),
|
||||||
summary_diffs: text({ mode: "json" }).$type<Snapshot.FileDiff[]>(),
|
summary_diffs: text({ mode: "json" }).$type<Snapshot.FileDiff[]>(),
|
||||||
|
metadata: text({ mode: "json" }).$type<Record<string, unknown>>(),
|
||||||
cost: real().notNull().default(0),
|
cost: real().notNull().default(0),
|
||||||
tokens_input: integer().notNull().default(0),
|
tokens_input: integer().notNull().default(0),
|
||||||
tokens_output: integer().notNull().default(0),
|
tokens_output: integer().notNull().default(0),
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ export function fromRow(row: SessionRow): Info {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
share,
|
share,
|
||||||
|
metadata: row.metadata ?? undefined,
|
||||||
revert,
|
revert,
|
||||||
permission: row.permission ? [...row.permission] : undefined,
|
permission: row.permission ? [...row.permission] : undefined,
|
||||||
time: {
|
time: {
|
||||||
@@ -129,6 +130,7 @@ export function toRow(info: Info) {
|
|||||||
summary_deletions: info.summary?.deletions,
|
summary_deletions: info.summary?.deletions,
|
||||||
summary_files: info.summary?.files,
|
summary_files: info.summary?.files,
|
||||||
summary_diffs: info.summary?.diffs,
|
summary_diffs: info.summary?.diffs,
|
||||||
|
metadata: info.metadata,
|
||||||
cost: info.cost ?? 0,
|
cost: info.cost ?? 0,
|
||||||
tokens_input: (info.tokens ?? EmptyTokens).input,
|
tokens_input: (info.tokens ?? EmptyTokens).input,
|
||||||
tokens_output: (info.tokens ?? EmptyTokens).output,
|
tokens_output: (info.tokens ?? EmptyTokens).output,
|
||||||
@@ -205,6 +207,8 @@ const Model = Schema.Struct({
|
|||||||
variant: optionalOmitUndefined(Schema.String),
|
variant: optionalOmitUndefined(Schema.String),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const Metadata = Schema.Record(Schema.String, Schema.Any)
|
||||||
|
|
||||||
export const Info = Schema.Struct({
|
export const Info = Schema.Struct({
|
||||||
id: SessionID,
|
id: SessionID,
|
||||||
slug: Schema.String,
|
slug: Schema.String,
|
||||||
@@ -221,6 +225,7 @@ export const Info = Schema.Struct({
|
|||||||
agent: optionalOmitUndefined(Schema.String),
|
agent: optionalOmitUndefined(Schema.String),
|
||||||
model: optionalOmitUndefined(Model),
|
model: optionalOmitUndefined(Model),
|
||||||
version: Schema.String,
|
version: Schema.String,
|
||||||
|
metadata: optionalOmitUndefined(Metadata),
|
||||||
time: Time,
|
time: Time,
|
||||||
permission: optionalOmitUndefined(Permission.Ruleset),
|
permission: optionalOmitUndefined(Permission.Ruleset),
|
||||||
revert: optionalOmitUndefined(Revert),
|
revert: optionalOmitUndefined(Revert),
|
||||||
@@ -246,6 +251,7 @@ export const CreateInput = Schema.optional(
|
|||||||
title: Schema.optional(Schema.String),
|
title: Schema.optional(Schema.String),
|
||||||
agent: Schema.optional(Schema.String),
|
agent: Schema.optional(Schema.String),
|
||||||
model: Schema.optional(Model),
|
model: Schema.optional(Model),
|
||||||
|
metadata: Schema.optional(Metadata),
|
||||||
permission: Schema.optional(Permission.Ruleset),
|
permission: Schema.optional(Permission.Ruleset),
|
||||||
workspaceID: Schema.optional(WorkspaceID),
|
workspaceID: Schema.optional(WorkspaceID),
|
||||||
}),
|
}),
|
||||||
@@ -264,6 +270,10 @@ export const SetArchivedInput = Schema.Struct({
|
|||||||
sessionID: SessionID,
|
sessionID: SessionID,
|
||||||
time: Schema.optional(ArchivedTimestamp),
|
time: Schema.optional(ArchivedTimestamp),
|
||||||
})
|
})
|
||||||
|
export const SetMetadataInput = Schema.Struct({
|
||||||
|
sessionID: SessionID,
|
||||||
|
metadata: Metadata,
|
||||||
|
})
|
||||||
export const SetPermissionInput = Schema.Struct({
|
export const SetPermissionInput = Schema.Struct({
|
||||||
sessionID: SessionID,
|
sessionID: SessionID,
|
||||||
permission: Permission.Ruleset,
|
permission: Permission.Ruleset,
|
||||||
@@ -320,6 +330,7 @@ const UpdatedInfo = Schema.Struct({
|
|||||||
agent: Schema.optional(Schema.NullOr(Schema.String)),
|
agent: Schema.optional(Schema.NullOr(Schema.String)),
|
||||||
model: Schema.optional(Schema.NullOr(Model)),
|
model: Schema.optional(Schema.NullOr(Model)),
|
||||||
version: Schema.optional(Schema.NullOr(Schema.String)),
|
version: Schema.optional(Schema.NullOr(Schema.String)),
|
||||||
|
metadata: Schema.optional(Schema.NullOr(Metadata)),
|
||||||
time: Schema.optional(UpdatedTime),
|
time: Schema.optional(UpdatedTime),
|
||||||
permission: Schema.optional(Schema.NullOr(Permission.Ruleset)),
|
permission: Schema.optional(Schema.NullOr(Permission.Ruleset)),
|
||||||
revert: Schema.optional(Schema.NullOr(Revert)),
|
revert: Schema.optional(Schema.NullOr(Revert)),
|
||||||
@@ -455,6 +466,7 @@ export interface Interface {
|
|||||||
title?: string
|
title?: string
|
||||||
agent?: string
|
agent?: string
|
||||||
model?: Schema.Schema.Type<typeof Model>
|
model?: Schema.Schema.Type<typeof Model>
|
||||||
|
metadata?: typeof Metadata.Type
|
||||||
permission?: Permission.Ruleset
|
permission?: Permission.Ruleset
|
||||||
workspaceID?: WorkspaceID
|
workspaceID?: WorkspaceID
|
||||||
}) => Effect.Effect<Info>
|
}) => Effect.Effect<Info>
|
||||||
@@ -463,6 +475,7 @@ export interface Interface {
|
|||||||
readonly get: (id: SessionID) => Effect.Effect<Info, NotFound>
|
readonly get: (id: SessionID) => Effect.Effect<Info, NotFound>
|
||||||
readonly setTitle: (input: { sessionID: SessionID; title: string }) => Effect.Effect<void>
|
readonly setTitle: (input: { sessionID: SessionID; title: string }) => Effect.Effect<void>
|
||||||
readonly setArchived: (input: { sessionID: SessionID; time?: number }) => 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 setPermission: (input: { sessionID: SessionID; permission: Permission.Ruleset }) => Effect.Effect<void>
|
||||||
readonly setRevert: (input: {
|
readonly setRevert: (input: {
|
||||||
sessionID: SessionID
|
sessionID: SessionID
|
||||||
@@ -529,6 +542,7 @@ export const layer: Layer.Layer<
|
|||||||
workspaceID?: WorkspaceID
|
workspaceID?: WorkspaceID
|
||||||
directory: string
|
directory: string
|
||||||
path?: string
|
path?: string
|
||||||
|
metadata?: typeof Metadata.Type
|
||||||
permission?: Permission.Ruleset
|
permission?: Permission.Ruleset
|
||||||
}) {
|
}) {
|
||||||
const ctx = yield* InstanceState.context
|
const ctx = yield* InstanceState.context
|
||||||
@@ -544,6 +558,7 @@ export const layer: Layer.Layer<
|
|||||||
title: input.title ?? createDefaultTitle(!!input.parentID),
|
title: input.title ?? createDefaultTitle(!!input.parentID),
|
||||||
agent: input.agent,
|
agent: input.agent,
|
||||||
model: input.model,
|
model: input.model,
|
||||||
|
metadata: input.metadata,
|
||||||
permission: input.permission ? [...input.permission] : undefined,
|
permission: input.permission ? [...input.permission] : undefined,
|
||||||
cost: 0,
|
cost: 0,
|
||||||
tokens: EmptyTokens,
|
tokens: EmptyTokens,
|
||||||
@@ -659,6 +674,7 @@ export const layer: Layer.Layer<
|
|||||||
title?: string
|
title?: string
|
||||||
agent?: string
|
agent?: string
|
||||||
model?: Schema.Schema.Type<typeof Model>
|
model?: Schema.Schema.Type<typeof Model>
|
||||||
|
metadata?: typeof Metadata.Type
|
||||||
permission?: Permission.Ruleset
|
permission?: Permission.Ruleset
|
||||||
workspaceID?: WorkspaceID
|
workspaceID?: WorkspaceID
|
||||||
}) {
|
}) {
|
||||||
@@ -671,6 +687,7 @@ export const layer: Layer.Layer<
|
|||||||
title: input?.title,
|
title: input?.title,
|
||||||
agent: input?.agent,
|
agent: input?.agent,
|
||||||
model: input?.model,
|
model: input?.model,
|
||||||
|
metadata: input?.metadata,
|
||||||
permission: input?.permission,
|
permission: input?.permission,
|
||||||
workspaceID: input?.workspaceID ?? workspace,
|
workspaceID: input?.workspaceID ?? workspace,
|
||||||
})
|
})
|
||||||
@@ -685,6 +702,7 @@ export const layer: Layer.Layer<
|
|||||||
path: sessionPath(ctx.worktree, ctx.directory),
|
path: sessionPath(ctx.worktree, ctx.directory),
|
||||||
workspaceID: original.workspaceID,
|
workspaceID: original.workspaceID,
|
||||||
title,
|
title,
|
||||||
|
metadata: structuredClone(original.metadata),
|
||||||
})
|
})
|
||||||
const msgs = yield* messages({ sessionID: input.sessionID })
|
const msgs = yield* messages({ sessionID: input.sessionID })
|
||||||
const idMap = new Map<string, MessageID>()
|
const idMap = new Map<string, MessageID>()
|
||||||
@@ -732,6 +750,10 @@ export const layer: Layer.Layer<
|
|||||||
yield* patch(input.sessionID, { time: { archived: input.time } })
|
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: {
|
const setPermission = Effect.fn("Session.setPermission")(function* (input: {
|
||||||
sessionID: SessionID
|
sessionID: SessionID
|
||||||
permission: Permission.Ruleset
|
permission: Permission.Ruleset
|
||||||
@@ -844,6 +866,7 @@ export const layer: Layer.Layer<
|
|||||||
get,
|
get,
|
||||||
setTitle,
|
setTitle,
|
||||||
setArchived,
|
setArchived,
|
||||||
|
setMetadata,
|
||||||
setPermission,
|
setPermission,
|
||||||
setRevert,
|
setRevert,
|
||||||
clearRevert,
|
clearRevert,
|
||||||
|
|||||||
@@ -16,6 +16,85 @@ afterEach(async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("session action routes", () => {
|
describe("session action routes", () => {
|
||||||
|
it.instance(
|
||||||
|
"session routes expose metadata on create, update, get, and fork",
|
||||||
|
() =>
|
||||||
|
Effect.gen(function* () {
|
||||||
|
const test = yield* TestInstance
|
||||||
|
const app = Server.Default().app
|
||||||
|
const headers = { "Content-Type": "application/json", "x-opencode-directory": test.directory }
|
||||||
|
|
||||||
|
const created = yield* Effect.promise(() =>
|
||||||
|
Promise.resolve(
|
||||||
|
app.request("/session", {
|
||||||
|
method: "POST",
|
||||||
|
headers,
|
||||||
|
body: JSON.stringify({
|
||||||
|
title: "meta-session",
|
||||||
|
metadata: { source: "sdk", trace: { id: "abc" } },
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
expect(created.status).toBe(200)
|
||||||
|
|
||||||
|
const session = (yield* Effect.promise(() => created.json())) as SessionNs.Info
|
||||||
|
expect(session.metadata).toEqual({ source: "sdk", trace: { id: "abc" } })
|
||||||
|
|
||||||
|
const updated = yield* Effect.promise(() =>
|
||||||
|
Promise.resolve(
|
||||||
|
app.request(`/session/${session.id}`, {
|
||||||
|
method: "PATCH",
|
||||||
|
headers,
|
||||||
|
body: JSON.stringify({ metadata: { source: "sdk", trace: { id: "def" }, tags: ["one"] } }),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
expect(updated.status).toBe(200)
|
||||||
|
|
||||||
|
const next = (yield* Effect.promise(() => updated.json())) as SessionNs.Info
|
||||||
|
expect(next.metadata).toEqual({ source: "sdk", trace: { id: "def" }, tags: ["one"] })
|
||||||
|
|
||||||
|
const fetched = yield* Effect.promise(() =>
|
||||||
|
Promise.resolve(
|
||||||
|
app.request(`/session/${session.id}`, { headers: { "x-opencode-directory": test.directory } }),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
expect(fetched.status).toBe(200)
|
||||||
|
expect(((yield* Effect.promise(() => fetched.json())) as SessionNs.Info).metadata).toEqual(next.metadata)
|
||||||
|
|
||||||
|
const forked = yield* Effect.promise(() =>
|
||||||
|
Promise.resolve(
|
||||||
|
app.request(`/session/${session.id}/fork`, {
|
||||||
|
method: "POST",
|
||||||
|
headers,
|
||||||
|
body: JSON.stringify({}),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
expect(forked.status).toBe(200)
|
||||||
|
|
||||||
|
const fork = (yield* Effect.promise(() => forked.json())) as SessionNs.Info
|
||||||
|
expect(fork.metadata).toEqual(next.metadata)
|
||||||
|
|
||||||
|
const reset = yield* Effect.promise(() =>
|
||||||
|
Promise.resolve(
|
||||||
|
app.request(`/session/${session.id}`, {
|
||||||
|
method: "PATCH",
|
||||||
|
headers,
|
||||||
|
body: JSON.stringify({ metadata: {} }),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
expect(reset.status).toBe(200)
|
||||||
|
expect(((yield* Effect.promise(() => reset.json())) as SessionNs.Info).metadata).toEqual({})
|
||||||
|
|
||||||
|
yield* SessionNs.Service.use((svc) => svc.remove(fork.id).pipe(Effect.ignore))
|
||||||
|
yield* SessionNs.Service.use((svc) => svc.remove(session.id).pipe(Effect.ignore))
|
||||||
|
}),
|
||||||
|
{ git: true },
|
||||||
|
)
|
||||||
|
|
||||||
it.instance(
|
it.instance(
|
||||||
"abort route returns success",
|
"abort route returns success",
|
||||||
() =>
|
() =>
|
||||||
|
|||||||
@@ -227,4 +227,20 @@ describe("session.list", () => {
|
|||||||
}),
|
}),
|
||||||
{ git: true },
|
{ git: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
it.instance(
|
||||||
|
"includes metadata in listed sessions",
|
||||||
|
() =>
|
||||||
|
Effect.gen(function* () {
|
||||||
|
const meta = { source: "sdk", trace: { id: "abc" } }
|
||||||
|
const created = yield* withSession({ title: "meta-session", metadata: meta })
|
||||||
|
|
||||||
|
const listed = (yield* SessionNs.Service.use((session) => session.list({ search: "meta-session" }))).find(
|
||||||
|
(item) => item.id === created.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(listed?.metadata).toEqual(meta)
|
||||||
|
}),
|
||||||
|
{ git: true },
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ describe("Session.Info", () => {
|
|||||||
share: { url: "https://share.example.com/s/1" },
|
share: { url: "https://share.example.com/s/1" },
|
||||||
title: "Full session",
|
title: "Full session",
|
||||||
version: "1.0.0",
|
version: "1.0.0",
|
||||||
|
metadata: { source: "test" },
|
||||||
time: { created: 100, updated: 200, compacting: 150, archived: 300 },
|
time: { created: 100, updated: 200, compacting: 150, archived: 300 },
|
||||||
permission: [{ action: "allow" as const, pattern: "*", permission: "read" }],
|
permission: [{ action: "allow" as const, pattern: "*", permission: "read" }],
|
||||||
revert: {
|
revert: {
|
||||||
@@ -157,6 +158,7 @@ describe("Session input schemas", () => {
|
|||||||
const populated = {
|
const populated = {
|
||||||
parentID: sessionID,
|
parentID: sessionID,
|
||||||
title: "child",
|
title: "child",
|
||||||
|
metadata: { source: "test" },
|
||||||
permission: [{ action: "ask" as const, pattern: "*", permission: "bash" }],
|
permission: [{ action: "ask" as const, pattern: "*", permission: "bash" }],
|
||||||
workspaceID,
|
workspaceID,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,4 +184,35 @@ describe("Session", () => {
|
|||||||
expect(Exit.isFailure(getExit)).toBe(true)
|
expect(Exit.isFailure(getExit)).toBe(true)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
it.instance("persists metadata and copies it on fork by default", () =>
|
||||||
|
Effect.gen(function* () {
|
||||||
|
const session = yield* SessionNs.Service
|
||||||
|
const meta = { source: "sdk", trace: { id: "abc" } }
|
||||||
|
const created = yield* Effect.acquireRelease(session.create({ title: "with-meta", metadata: meta }), (info) =>
|
||||||
|
session.remove(info.id).pipe(Effect.ignore),
|
||||||
|
)
|
||||||
|
const saved = yield* session.get(created.id)
|
||||||
|
const fork = yield* Effect.acquireRelease(session.fork({ sessionID: created.id }), (info) =>
|
||||||
|
session.remove(info.id).pipe(Effect.ignore),
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(saved.metadata).toEqual(meta)
|
||||||
|
expect(fork.metadata).toEqual(meta)
|
||||||
|
expect(fork.metadata).not.toBe(meta)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
it.instance("omits metadata when not provided", () =>
|
||||||
|
Effect.gen(function* () {
|
||||||
|
const session = yield* SessionNs.Service
|
||||||
|
const created = yield* Effect.acquireRelease(session.create({ title: "empty-meta" }), (info) =>
|
||||||
|
session.remove(info.id).pipe(Effect.ignore),
|
||||||
|
)
|
||||||
|
const saved = yield* session.get(created.id)
|
||||||
|
|
||||||
|
expect(created.metadata).toBeUndefined()
|
||||||
|
expect(saved.metadata).toBeUndefined()
|
||||||
|
}),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3100,6 +3100,9 @@ export class Session2 extends HeyApiClient {
|
|||||||
providerID: string
|
providerID: string
|
||||||
variant?: string
|
variant?: string
|
||||||
}
|
}
|
||||||
|
metadata?: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
permission?: PermissionRuleset
|
permission?: PermissionRuleset
|
||||||
workspaceID?: string
|
workspaceID?: string
|
||||||
},
|
},
|
||||||
@@ -3116,6 +3119,7 @@ export class Session2 extends HeyApiClient {
|
|||||||
{ in: "body", key: "title" },
|
{ in: "body", key: "title" },
|
||||||
{ in: "body", key: "agent" },
|
{ in: "body", key: "agent" },
|
||||||
{ in: "body", key: "model" },
|
{ in: "body", key: "model" },
|
||||||
|
{ in: "body", key: "metadata" },
|
||||||
{ in: "body", key: "permission" },
|
{ in: "body", key: "permission" },
|
||||||
{ in: "body", key: "workspaceID" },
|
{ in: "body", key: "workspaceID" },
|
||||||
],
|
],
|
||||||
@@ -3239,6 +3243,9 @@ export class Session2 extends HeyApiClient {
|
|||||||
directory?: string
|
directory?: string
|
||||||
workspace?: string
|
workspace?: string
|
||||||
title?: string
|
title?: string
|
||||||
|
metadata?: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
permission?: PermissionRuleset
|
permission?: PermissionRuleset
|
||||||
time?: {
|
time?: {
|
||||||
archived?: number
|
archived?: number
|
||||||
@@ -3255,6 +3262,7 @@ export class Session2 extends HeyApiClient {
|
|||||||
{ in: "query", key: "directory" },
|
{ in: "query", key: "directory" },
|
||||||
{ in: "query", key: "workspace" },
|
{ in: "query", key: "workspace" },
|
||||||
{ in: "body", key: "title" },
|
{ in: "body", key: "title" },
|
||||||
|
{ in: "body", key: "metadata" },
|
||||||
{ in: "body", key: "permission" },
|
{ in: "body", key: "permission" },
|
||||||
{ in: "body", key: "time" },
|
{ in: "body", key: "time" },
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -780,6 +780,9 @@ export type Session = {
|
|||||||
variant?: string
|
variant?: string
|
||||||
}
|
}
|
||||||
version: string
|
version: string
|
||||||
|
metadata?: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
time: {
|
time: {
|
||||||
created: number
|
created: number
|
||||||
updated: number
|
updated: number
|
||||||
@@ -1516,6 +1519,9 @@ export type GlobalSession = {
|
|||||||
variant?: string
|
variant?: string
|
||||||
}
|
}
|
||||||
version: string
|
version: string
|
||||||
|
metadata?: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
time: {
|
time: {
|
||||||
created: number
|
created: number
|
||||||
updated: number
|
updated: number
|
||||||
@@ -2086,6 +2092,9 @@ export type SyncEventSessionUpdated = {
|
|||||||
variant?: string
|
variant?: string
|
||||||
} | null
|
} | null
|
||||||
version?: string | null
|
version?: string | null
|
||||||
|
metadata?: {
|
||||||
|
[key: string]: unknown
|
||||||
|
} | null
|
||||||
time?: {
|
time?: {
|
||||||
created?: number | null
|
created?: number | null
|
||||||
updated?: number | null
|
updated?: number | null
|
||||||
@@ -6093,6 +6102,9 @@ export type SessionCreateData = {
|
|||||||
providerID: string
|
providerID: string
|
||||||
variant?: string
|
variant?: string
|
||||||
}
|
}
|
||||||
|
metadata?: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
permission?: PermissionRuleset
|
permission?: PermissionRuleset
|
||||||
workspaceID?: string
|
workspaceID?: string
|
||||||
}
|
}
|
||||||
@@ -6223,6 +6235,9 @@ export type SessionGetResponse = SessionGetResponses[keyof SessionGetResponses]
|
|||||||
export type SessionUpdateData = {
|
export type SessionUpdateData = {
|
||||||
body?: {
|
body?: {
|
||||||
title?: string
|
title?: string
|
||||||
|
metadata?: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
permission?: PermissionRuleset
|
permission?: PermissionRuleset
|
||||||
time?: {
|
time?: {
|
||||||
archived?: number
|
archived?: number
|
||||||
|
|||||||
@@ -5185,6 +5185,9 @@
|
|||||||
"required": ["id", "providerID"],
|
"required": ["id", "providerID"],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
|
"metadata": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"permission": {
|
"permission": {
|
||||||
"$ref": "#/components/schemas/PermissionRuleset"
|
"$ref": "#/components/schemas/PermissionRuleset"
|
||||||
},
|
},
|
||||||
@@ -5509,6 +5512,9 @@
|
|||||||
"title": {
|
"title": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"metadata": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"permission": {
|
"permission": {
|
||||||
"$ref": "#/components/schemas/PermissionRuleset"
|
"$ref": "#/components/schemas/PermissionRuleset"
|
||||||
},
|
},
|
||||||
@@ -12819,6 +12825,9 @@
|
|||||||
"version": {
|
"version": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"metadata": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"time": {
|
"time": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -14912,6 +14921,9 @@
|
|||||||
"version": {
|
"version": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"metadata": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"time": {
|
"time": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -16758,6 +16770,16 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"metadata": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"time": {
|
"time": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
Reference in New Issue
Block a user