mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-25 07:00:48 +09:00
feat: add immediate context compaction API, UI button, and /compact slash command
- Add POST /bots/:bot_id/sessions/:session_id/compact endpoint for synchronous context compaction with fallback to chat model when no dedicated compaction model is configured - Add "Compact Now" button to session info panel in the web UI - Add /compact slash command for triggering compaction from chat - Regenerate OpenAPI spec and TypeScript SDK
This commit is contained in:
@@ -229,7 +229,10 @@
|
||||
"infoCacheWrite": "Cache Write",
|
||||
"infoSkills": "Skills",
|
||||
"infoNoSkills": "No skills used in this session",
|
||||
"infoNoData": "No data available"
|
||||
"infoNoData": "No data available",
|
||||
"compactNow": "Compact Now",
|
||||
"compactSuccess": "Context compaction completed",
|
||||
"compactFailed": "Context compaction failed"
|
||||
},
|
||||
"models": {
|
||||
"title": "Models",
|
||||
|
||||
@@ -225,7 +225,10 @@
|
||||
"infoCacheWrite": "Cache 写入",
|
||||
"infoSkills": "Skills",
|
||||
"infoNoSkills": "此会话未使用任何 Skill",
|
||||
"infoNoData": "暂无数据"
|
||||
"infoNoData": "暂无数据",
|
||||
"compactNow": "立即压缩",
|
||||
"compactSuccess": "上下文压缩完成",
|
||||
"compactFailed": "上下文压缩失败"
|
||||
},
|
||||
"models": {
|
||||
"title": "模型",
|
||||
|
||||
@@ -65,6 +65,26 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Compact Now -->
|
||||
<div class="mt-3">
|
||||
<button
|
||||
type="button"
|
||||
class="flex items-center justify-center gap-1.5 w-full px-2 py-1.5 rounded-md text-xs font-medium text-foreground bg-accent hover:bg-accent/80 transition-colors disabled:opacity-50 disabled:pointer-events-none"
|
||||
:disabled="!sessionId || usedTokens <= 0 || isCompacting"
|
||||
@click="triggerCompact"
|
||||
>
|
||||
<Loader2
|
||||
v-if="isCompacting"
|
||||
class="size-3 animate-spin"
|
||||
/>
|
||||
<Minimize2
|
||||
v-else
|
||||
class="size-3"
|
||||
/>
|
||||
{{ $t('chat.compactNow') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Skills -->
|
||||
<div class="mt-3">
|
||||
<p class="text-[11px] font-medium text-muted-foreground uppercase tracking-wider mb-1.5">
|
||||
@@ -99,13 +119,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, inject } from 'vue'
|
||||
import { computed, inject, ref } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useQuery } from '@pinia/colada'
|
||||
import { Sparkles, ExternalLink } from 'lucide-vue-next'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useQuery, useQueryCache } from '@pinia/colada'
|
||||
import { toast } from 'vue-sonner'
|
||||
import { Sparkles, ExternalLink, Loader2, Minimize2 } from 'lucide-vue-next'
|
||||
import { ScrollArea } from '@memohai/ui'
|
||||
import { getBotsByBotIdSessionsBySessionIdStatus } from '@memohai/sdk'
|
||||
import { getBotsByBotIdSessionsBySessionIdStatus, postBotsByBotIdSessionsBySessionIdCompact } from '@memohai/sdk'
|
||||
import type { HandlersSessionInfoResponse } from '@memohai/sdk'
|
||||
import { resolveApiErrorMessage } from '@/utils/api-error'
|
||||
import { useChatStore } from '@/store/chat-list'
|
||||
import { openInFileManagerKey } from '../composables/useFileManagerProvider'
|
||||
|
||||
@@ -114,9 +137,11 @@ const props = defineProps<{
|
||||
overrideModelId?: string
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const chatStore = useChatStore()
|
||||
const { currentBotId, sessionId } = storeToRefs(chatStore)
|
||||
const openInFileManager = inject(openInFileManagerKey, undefined)
|
||||
const queryCache = useQueryCache()
|
||||
|
||||
const { data: info } = useQuery({
|
||||
key: () => ['session-status', currentBotId.value ?? '', sessionId.value ?? '', props.overrideModelId ?? ''],
|
||||
@@ -165,4 +190,28 @@ function formatTokenCount(n: number): string {
|
||||
function openSkillFile(skillName: string) {
|
||||
openInFileManager?.(`/data/skills/${skillName}/SKILL.md`, false)
|
||||
}
|
||||
|
||||
const isCompacting = ref(false)
|
||||
|
||||
async function triggerCompact() {
|
||||
const botId = currentBotId.value
|
||||
const sid = sessionId.value
|
||||
if (!botId || !sid || isCompacting.value) return
|
||||
|
||||
isCompacting.value = true
|
||||
try {
|
||||
await postBotsByBotIdSessionsBySessionIdCompact({
|
||||
path: { bot_id: botId, session_id: sid },
|
||||
throwOnError: true,
|
||||
})
|
||||
toast.success(t('chat.compactSuccess'))
|
||||
queryCache.invalidateQueries({ key: ['session-status', botId, sid] })
|
||||
}
|
||||
catch (error) {
|
||||
toast.error(resolveApiErrorMessage(error, t('chat.compactFailed')))
|
||||
}
|
||||
finally {
|
||||
isCompacting.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
+5
-2
@@ -337,6 +337,7 @@ func provideChannelRouter(
|
||||
emailService *emailpkg.Service,
|
||||
emailOutboxService *emailpkg.OutboxService,
|
||||
heartbeatService *heartbeat.Service,
|
||||
compactionService *compaction.Service,
|
||||
queries *dbsqlc.Queries,
|
||||
containerdHandler *handlers.ContainerdHandler,
|
||||
manager *workspace.Manager,
|
||||
@@ -366,7 +367,7 @@ func provideChannelRouter(
|
||||
processor.SetStreamObserver(local.NewRouteHubBroadcaster(hub))
|
||||
processor.SetDispatcher(inbound.NewRouteDispatcher(log))
|
||||
processor.SetTtsService(ttsService, &settingsTtsModelResolver{settings: settingsService})
|
||||
processor.SetCommandHandler(command.NewHandler(
|
||||
cmdHandler := command.NewHandler(
|
||||
log,
|
||||
&command.BotMemberRoleAdapter{BotService: botService},
|
||||
scheduleService,
|
||||
@@ -384,7 +385,9 @@ func provideChannelRouter(
|
||||
aclService,
|
||||
&commandSkillLoaderAdapter{handler: containerdHandler},
|
||||
&commandContainerFSAdapter{manager: manager},
|
||||
))
|
||||
)
|
||||
cmdHandler.SetCompactionService(compactionService, queries)
|
||||
processor.SetCommandHandler(cmdHandler)
|
||||
return processor
|
||||
}
|
||||
|
||||
|
||||
@@ -17,5 +17,6 @@ func (h *Handler) buildRegistry() *Registry {
|
||||
r.RegisterGroup(h.buildFSGroup())
|
||||
r.RegisterGroup(h.buildStatusGroup())
|
||||
r.RegisterGroup(h.buildAccessGroup())
|
||||
r.RegisterGroup(h.buildCompactGroup())
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/memohai/memoh/internal/compaction"
|
||||
"github.com/memohai/memoh/internal/db"
|
||||
"github.com/memohai/memoh/internal/models"
|
||||
"github.com/memohai/memoh/internal/providers"
|
||||
)
|
||||
|
||||
func (h *Handler) buildCompactGroup() *CommandGroup {
|
||||
g := newCommandGroup("compact", "Compact conversation context")
|
||||
g.DefaultAction = "run"
|
||||
g.Register(SubCommand{
|
||||
Name: "run",
|
||||
Usage: "run - Compact the current session's context immediately",
|
||||
IsWrite: true,
|
||||
Handler: func(cc CommandContext) (string, error) {
|
||||
if h.compactionService == nil {
|
||||
return "Compaction service is not available.", nil
|
||||
}
|
||||
sessionID := cc.SessionID
|
||||
if sessionID == "" {
|
||||
botUUID, err := db.ParseUUID(cc.BotID)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid bot id: %w", err)
|
||||
}
|
||||
latestUUID, err := h.queries.GetLatestSessionIDByBot(cc.Ctx, botUUID)
|
||||
if err != nil {
|
||||
return "No active session found.", nil
|
||||
}
|
||||
sessionID = uuid.UUID(latestUUID.Bytes).String()
|
||||
}
|
||||
|
||||
cfg, err := h.buildCompactConfig(cc, sessionID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := h.compactionService.RunCompactionSync(cc.Ctx, cfg); err != nil {
|
||||
return "", fmt.Errorf("compaction failed: %w", err)
|
||||
}
|
||||
return "Context compaction completed successfully.", nil
|
||||
},
|
||||
})
|
||||
return g
|
||||
}
|
||||
|
||||
func (h *Handler) buildCompactConfig(cc CommandContext, sessionID string) (compaction.TriggerConfig, error) {
|
||||
botSettings, err := h.settingsService.GetBot(cc.Ctx, cc.BotID)
|
||||
if err != nil {
|
||||
return compaction.TriggerConfig{}, fmt.Errorf("failed to load settings: %w", err)
|
||||
}
|
||||
modelID := botSettings.CompactionModelID
|
||||
if modelID == "" {
|
||||
modelID = botSettings.ChatModelID
|
||||
}
|
||||
if modelID == "" {
|
||||
return compaction.TriggerConfig{}, errors.New("no compaction or chat model configured for this bot")
|
||||
}
|
||||
|
||||
compactModel, err := h.modelsService.GetByID(cc.Ctx, modelID)
|
||||
if err != nil {
|
||||
return compaction.TriggerConfig{}, fmt.Errorf("failed to load compaction model: %w", err)
|
||||
}
|
||||
compactProvider, err := models.FetchProviderByID(cc.Ctx, h.sqlcQueries, compactModel.ProviderID)
|
||||
if err != nil {
|
||||
return compaction.TriggerConfig{}, fmt.Errorf("failed to load provider: %w", err)
|
||||
}
|
||||
creds, err := h.providersService.ResolveModelCredentials(cc.Ctx, compactProvider)
|
||||
if err != nil {
|
||||
return compaction.TriggerConfig{}, fmt.Errorf("failed to resolve credentials: %w", err)
|
||||
}
|
||||
|
||||
cfg := compaction.TriggerConfig{
|
||||
BotID: cc.BotID,
|
||||
SessionID: sessionID,
|
||||
ModelID: compactModel.ModelID,
|
||||
ClientType: compactProvider.ClientType,
|
||||
APIKey: creds.APIKey,
|
||||
CodexAccountID: creds.CodexAccountID,
|
||||
BaseURL: providers.ProviderConfigString(compactProvider, "base_url"),
|
||||
Ratio: 100,
|
||||
TotalInputTokens: 1,
|
||||
}
|
||||
if compactModel.Config.ContextWindow != nil && *compactModel.Config.ContextWindow > 0 {
|
||||
cfg.MaxCompactTokens = *compactModel.Config.ContextWindow * 90 / 100
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
|
||||
"github.com/memohai/memoh/internal/bots"
|
||||
"github.com/memohai/memoh/internal/browsercontexts"
|
||||
"github.com/memohai/memoh/internal/compaction"
|
||||
"github.com/memohai/memoh/internal/db/sqlc"
|
||||
emailpkg "github.com/memohai/memoh/internal/email"
|
||||
"github.com/memohai/memoh/internal/heartbeat"
|
||||
"github.com/memohai/memoh/internal/mcp"
|
||||
@@ -56,7 +58,9 @@ type Handler struct {
|
||||
emailService *emailpkg.Service
|
||||
emailOutboxService *emailpkg.OutboxService
|
||||
heartbeatService *heartbeat.Service
|
||||
compactionService *compaction.Service
|
||||
queries CommandQueries
|
||||
sqlcQueries *sqlc.Queries
|
||||
aclEvaluator AccessEvaluator
|
||||
skillLoader SkillLoader
|
||||
containerFS ContainerFS
|
||||
@@ -124,6 +128,12 @@ func NewHandler(
|
||||
return h
|
||||
}
|
||||
|
||||
// SetCompactionService configures the compaction service for the /compact command.
|
||||
func (h *Handler) SetCompactionService(s *compaction.Service, q *sqlc.Queries) {
|
||||
h.compactionService = s
|
||||
h.sqlcQueries = q
|
||||
}
|
||||
|
||||
// topLevelCommands are standalone commands (no sub-actions) that are
|
||||
// recognised by IsCommand and listed in /help. They are handled outside
|
||||
// the regular resource-group dispatch (e.g. in the channel inbound
|
||||
|
||||
@@ -11,21 +11,42 @@ import (
|
||||
"github.com/memohai/memoh/internal/accounts"
|
||||
"github.com/memohai/memoh/internal/bots"
|
||||
"github.com/memohai/memoh/internal/compaction"
|
||||
"github.com/memohai/memoh/internal/db/sqlc"
|
||||
"github.com/memohai/memoh/internal/models"
|
||||
"github.com/memohai/memoh/internal/providers"
|
||||
"github.com/memohai/memoh/internal/settings"
|
||||
)
|
||||
|
||||
type CompactionHandler struct {
|
||||
service *compaction.Service
|
||||
botService *bots.Service
|
||||
accountService *accounts.Service
|
||||
logger *slog.Logger
|
||||
service *compaction.Service
|
||||
botService *bots.Service
|
||||
accountService *accounts.Service
|
||||
settingsService *settings.Service
|
||||
modelsService *models.Service
|
||||
queries *sqlc.Queries
|
||||
providersService *providers.Service
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewCompactionHandler(log *slog.Logger, service *compaction.Service, botService *bots.Service, accountService *accounts.Service) *CompactionHandler {
|
||||
func NewCompactionHandler(
|
||||
log *slog.Logger,
|
||||
service *compaction.Service,
|
||||
botService *bots.Service,
|
||||
accountService *accounts.Service,
|
||||
settingsService *settings.Service,
|
||||
modelsService *models.Service,
|
||||
queries *sqlc.Queries,
|
||||
providersService *providers.Service,
|
||||
) *CompactionHandler {
|
||||
return &CompactionHandler{
|
||||
service: service,
|
||||
botService: botService,
|
||||
accountService: accountService,
|
||||
logger: log.With(slog.String("handler", "compaction")),
|
||||
service: service,
|
||||
botService: botService,
|
||||
accountService: accountService,
|
||||
settingsService: settingsService,
|
||||
modelsService: modelsService,
|
||||
queries: queries,
|
||||
providersService: providersService,
|
||||
logger: log.With(slog.String("handler", "compaction")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +54,7 @@ func (h *CompactionHandler) Register(e *echo.Echo) {
|
||||
group := e.Group("/bots/:bot_id/compaction")
|
||||
group.GET("/logs", h.ListLogs)
|
||||
group.DELETE("/logs", h.DeleteLogs)
|
||||
e.POST("/bots/:bot_id/sessions/:session_id/compact", h.TriggerCompact)
|
||||
}
|
||||
|
||||
// ListLogs godoc
|
||||
@@ -94,6 +116,104 @@ func (h *CompactionHandler) DeleteLogs(c echo.Context) error {
|
||||
return c.NoContent(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// TriggerCompactResponse is the API response for triggering compaction.
|
||||
type TriggerCompactResponse struct {
|
||||
Status string `json:"status"`
|
||||
Summary string `json:"summary,omitempty"`
|
||||
MessageCount int `json:"message_count"`
|
||||
}
|
||||
|
||||
// TriggerCompact godoc
|
||||
// @Summary Trigger immediate context compaction
|
||||
// @Description Run context compaction synchronously for a session
|
||||
// @Tags compaction
|
||||
// @Param bot_id path string true "Bot ID"
|
||||
// @Param session_id path string true "Session ID"
|
||||
// @Success 200 {object} TriggerCompactResponse
|
||||
// @Failure 400 {object} ErrorResponse
|
||||
// @Failure 500 {object} ErrorResponse
|
||||
// @Router /bots/{bot_id}/sessions/{session_id}/compact [post].
|
||||
func (h *CompactionHandler) TriggerCompact(c echo.Context) error {
|
||||
userID, err := h.requireUserID(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
botID := strings.TrimSpace(c.Param("bot_id"))
|
||||
if botID == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "bot id is required")
|
||||
}
|
||||
if _, err := h.authorizeBotAccess(c.Request().Context(), userID, botID); err != nil {
|
||||
return err
|
||||
}
|
||||
sessionID := strings.TrimSpace(c.Param("session_id"))
|
||||
if sessionID == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "session id is required")
|
||||
}
|
||||
|
||||
cfg, err := h.buildTriggerConfig(c.Request().Context(), botID, sessionID)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
if err := h.service.RunCompactionSync(c.Request().Context(), cfg); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
logs, _, err := h.service.ListLogs(c.Request().Context(), botID, 1, 0)
|
||||
if err != nil || len(logs) == 0 {
|
||||
return c.JSON(http.StatusOK, TriggerCompactResponse{Status: "ok"})
|
||||
}
|
||||
latest := logs[0]
|
||||
return c.JSON(http.StatusOK, TriggerCompactResponse{
|
||||
Status: latest.Status,
|
||||
Summary: latest.Summary,
|
||||
MessageCount: latest.MessageCount,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *CompactionHandler) buildTriggerConfig(ctx context.Context, botID, sessionID string) (compaction.TriggerConfig, error) {
|
||||
botSettings, err := h.settingsService.GetBot(ctx, botID)
|
||||
if err != nil {
|
||||
return compaction.TriggerConfig{}, err
|
||||
}
|
||||
modelID := botSettings.CompactionModelID
|
||||
if modelID == "" {
|
||||
modelID = botSettings.ChatModelID
|
||||
}
|
||||
if modelID == "" {
|
||||
return compaction.TriggerConfig{}, echo.NewHTTPError(http.StatusBadRequest, "no compaction or chat model configured")
|
||||
}
|
||||
|
||||
compactModel, err := h.modelsService.GetByID(ctx, modelID)
|
||||
if err != nil {
|
||||
return compaction.TriggerConfig{}, err
|
||||
}
|
||||
compactProvider, err := models.FetchProviderByID(ctx, h.queries, compactModel.ProviderID)
|
||||
if err != nil {
|
||||
return compaction.TriggerConfig{}, err
|
||||
}
|
||||
creds, err := h.providersService.ResolveModelCredentials(ctx, compactProvider)
|
||||
if err != nil {
|
||||
return compaction.TriggerConfig{}, err
|
||||
}
|
||||
|
||||
cfg := compaction.TriggerConfig{
|
||||
BotID: botID,
|
||||
SessionID: sessionID,
|
||||
ModelID: compactModel.ModelID,
|
||||
ClientType: compactProvider.ClientType,
|
||||
APIKey: creds.APIKey,
|
||||
CodexAccountID: creds.CodexAccountID,
|
||||
BaseURL: providers.ProviderConfigString(compactProvider, "base_url"),
|
||||
Ratio: 100,
|
||||
TotalInputTokens: 1,
|
||||
}
|
||||
if compactModel.Config.ContextWindow != nil && *compactModel.Config.ContextWindow > 0 {
|
||||
cfg.MaxCompactTokens = *compactModel.Config.ContextWindow * 90 / 100
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func (*CompactionHandler) requireUserID(c echo.Context) (string, error) {
|
||||
return RequireChannelIdentityID(c)
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1054,6 +1054,12 @@ export type HandlersTokenUsageResponse = {
|
||||
schedule?: Array<HandlersDailyTokenUsage>;
|
||||
};
|
||||
|
||||
export type HandlersTriggerCompactResponse = {
|
||||
message_count?: number;
|
||||
status?: string;
|
||||
summary?: string;
|
||||
};
|
||||
|
||||
export type HandlersCreateSessionRequest = {
|
||||
channel_type?: string;
|
||||
metadata?: {
|
||||
@@ -1585,7 +1591,6 @@ export type SettingsSettings = {
|
||||
compaction_model_id?: string;
|
||||
compaction_ratio?: number;
|
||||
compaction_threshold?: number;
|
||||
context_token_budget?: number;
|
||||
discuss_probe_model_id?: string;
|
||||
heartbeat_enabled?: boolean;
|
||||
heartbeat_interval?: number;
|
||||
@@ -1610,7 +1615,6 @@ export type SettingsUpsertRequest = {
|
||||
compaction_model_id?: string;
|
||||
compaction_ratio?: number;
|
||||
compaction_threshold?: number;
|
||||
context_token_budget?: number;
|
||||
discuss_probe_model_id?: string;
|
||||
heartbeat_enabled?: boolean;
|
||||
heartbeat_interval?: number;
|
||||
@@ -5284,6 +5288,44 @@ export type PatchBotsByBotIdSessionsBySessionIdResponses = {
|
||||
|
||||
export type PatchBotsByBotIdSessionsBySessionIdResponse = PatchBotsByBotIdSessionsBySessionIdResponses[keyof PatchBotsByBotIdSessionsBySessionIdResponses];
|
||||
|
||||
export type PostBotsByBotIdSessionsBySessionIdCompactData = {
|
||||
body?: never;
|
||||
path: {
|
||||
/**
|
||||
* Bot ID
|
||||
*/
|
||||
bot_id: string;
|
||||
/**
|
||||
* Session ID
|
||||
*/
|
||||
session_id: string;
|
||||
};
|
||||
query?: never;
|
||||
url: '/bots/{bot_id}/sessions/{session_id}/compact';
|
||||
};
|
||||
|
||||
export type PostBotsByBotIdSessionsBySessionIdCompactErrors = {
|
||||
/**
|
||||
* Bad Request
|
||||
*/
|
||||
400: HandlersErrorResponse;
|
||||
/**
|
||||
* Internal Server Error
|
||||
*/
|
||||
500: HandlersErrorResponse;
|
||||
};
|
||||
|
||||
export type PostBotsByBotIdSessionsBySessionIdCompactError = PostBotsByBotIdSessionsBySessionIdCompactErrors[keyof PostBotsByBotIdSessionsBySessionIdCompactErrors];
|
||||
|
||||
export type PostBotsByBotIdSessionsBySessionIdCompactResponses = {
|
||||
/**
|
||||
* OK
|
||||
*/
|
||||
200: HandlersTriggerCompactResponse;
|
||||
};
|
||||
|
||||
export type PostBotsByBotIdSessionsBySessionIdCompactResponse = PostBotsByBotIdSessionsBySessionIdCompactResponses[keyof PostBotsByBotIdSessionsBySessionIdCompactResponses];
|
||||
|
||||
export type GetBotsByBotIdSessionsBySessionIdStatusData = {
|
||||
body?: never;
|
||||
path: {
|
||||
|
||||
+59
-6
@@ -4395,6 +4395,51 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bots/{bot_id}/sessions/{session_id}/compact": {
|
||||
"post": {
|
||||
"description": "Run context compaction synchronously for a session",
|
||||
"tags": [
|
||||
"compaction"
|
||||
],
|
||||
"summary": "Trigger immediate context compaction",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Bot ID",
|
||||
"name": "bot_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Session ID",
|
||||
"name": "session_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.TriggerCompactResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bots/{bot_id}/sessions/{session_id}/status": {
|
||||
"get": {
|
||||
"description": "Get aggregated info for a chat session including message count, context usage, cache stats, and used skills",
|
||||
@@ -11357,6 +11402,20 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"handlers.TriggerCompactResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"summary": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handlers.createSessionRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -12678,9 +12737,6 @@ const docTemplate = `{
|
||||
"compaction_threshold": {
|
||||
"type": "integer"
|
||||
},
|
||||
"context_token_budget": {
|
||||
"type": "integer"
|
||||
},
|
||||
"discuss_probe_model_id": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -12749,9 +12805,6 @@ const docTemplate = `{
|
||||
"compaction_threshold": {
|
||||
"type": "integer"
|
||||
},
|
||||
"context_token_budget": {
|
||||
"type": "integer"
|
||||
},
|
||||
"discuss_probe_model_id": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
+59
-6
@@ -4386,6 +4386,51 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bots/{bot_id}/sessions/{session_id}/compact": {
|
||||
"post": {
|
||||
"description": "Run context compaction synchronously for a session",
|
||||
"tags": [
|
||||
"compaction"
|
||||
],
|
||||
"summary": "Trigger immediate context compaction",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Bot ID",
|
||||
"name": "bot_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Session ID",
|
||||
"name": "session_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.TriggerCompactResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bots/{bot_id}/sessions/{session_id}/status": {
|
||||
"get": {
|
||||
"description": "Get aggregated info for a chat session including message count, context usage, cache stats, and used skills",
|
||||
@@ -11348,6 +11393,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"handlers.TriggerCompactResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"summary": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handlers.createSessionRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -12669,9 +12728,6 @@
|
||||
"compaction_threshold": {
|
||||
"type": "integer"
|
||||
},
|
||||
"context_token_budget": {
|
||||
"type": "integer"
|
||||
},
|
||||
"discuss_probe_model_id": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -12740,9 +12796,6 @@
|
||||
"compaction_threshold": {
|
||||
"type": "integer"
|
||||
},
|
||||
"context_token_budget": {
|
||||
"type": "integer"
|
||||
},
|
||||
"discuss_probe_model_id": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
+39
-4
@@ -1780,6 +1780,15 @@ definitions:
|
||||
$ref: '#/definitions/handlers.DailyTokenUsage'
|
||||
type: array
|
||||
type: object
|
||||
handlers.TriggerCompactResponse:
|
||||
properties:
|
||||
message_count:
|
||||
type: integer
|
||||
status:
|
||||
type: string
|
||||
summary:
|
||||
type: string
|
||||
type: object
|
||||
handlers.createSessionRequest:
|
||||
properties:
|
||||
channel_type:
|
||||
@@ -2659,8 +2668,6 @@ definitions:
|
||||
type: integer
|
||||
compaction_threshold:
|
||||
type: integer
|
||||
context_token_budget:
|
||||
type: integer
|
||||
discuss_probe_model_id:
|
||||
type: string
|
||||
heartbeat_enabled:
|
||||
@@ -2706,8 +2713,6 @@ definitions:
|
||||
type: integer
|
||||
compaction_threshold:
|
||||
type: integer
|
||||
context_token_budget:
|
||||
type: integer
|
||||
discuss_probe_model_id:
|
||||
type: string
|
||||
heartbeat_enabled:
|
||||
@@ -5766,6 +5771,36 @@ paths:
|
||||
summary: Update a session
|
||||
tags:
|
||||
- sessions
|
||||
/bots/{bot_id}/sessions/{session_id}/compact:
|
||||
post:
|
||||
description: Run context compaction synchronously for a session
|
||||
parameters:
|
||||
- description: Bot ID
|
||||
in: path
|
||||
name: bot_id
|
||||
required: true
|
||||
type: string
|
||||
- description: Session ID
|
||||
in: path
|
||||
name: session_id
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.TriggerCompactResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
summary: Trigger immediate context compaction
|
||||
tags:
|
||||
- compaction
|
||||
/bots/{bot_id}/sessions/{session_id}/status:
|
||||
get:
|
||||
description: Get aggregated info for a chat session including message count,
|
||||
|
||||
Reference in New Issue
Block a user