Files
Jonathan Miller aae7b65329
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Branch Policy Check / Verify merge target (pull_request) Successful in 2s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
PR RC Release / Build RC Release (pull_request) Successful in 2s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: PR Check / Validate PR (pull_request) Failing after 7s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report Issues (pull_request) Has been cancelled
fix(manifest): sync version_prefix + element_name, rename moko-platform everywhere
- manifest_sync.go: add VersionPrefix and ElementName to XML parse and DB sync
- deploy workflow: use manifest API for version prefix instead of hardcoded sed
- pre-release workflow: rename moko-platform paths to mokoplatform
- All workflow headers: rename moko-platform references
- manifest.xml: update root element to mokoplatform, add version-prefix field
- Server: symlink /opt/mokoplatform -> /opt/moko-platform for compatibility
2026-06-07 12:36:43 -05:00

135 lines
4.1 KiB
Go

// Copyright 2026 The MokoGitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package ai
import (
"context"
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/db"
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/timeutil"
)
// OrgSetting stores AI configuration for an organization.
type OrgSetting struct {
ID int64 `xorm:"pk autoincr"`
OrgID int64 `xorm:"UNIQUE NOT NULL"`
Enabled bool `xorm:"NOT NULL DEFAULT true"`
APIKeyEncrypted string `xorm:"TEXT"`
Model string `xorm:"VARCHAR(50) NOT NULL DEFAULT 'claude-sonnet-4-6'"`
RateLimitRequests int `xorm:"NOT NULL DEFAULT 100"`
RateLimitTokensMonth int64 `xorm:"NOT NULL DEFAULT 5000000"`
CreatedUnix timeutil.TimeStamp
UpdatedUnix timeutil.TimeStamp
}
func init() {
db.RegisterModel(new(OrgSetting))
db.RegisterModel(new(RepoSetting))
db.RegisterModel(new(UsageLog))
}
// TableName returns the table name for OrgSetting.
func (OrgSetting) TableName() string {
return "ai_org_setting"
}
// RepoSetting stores AI configuration for a repository.
type RepoSetting struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"UNIQUE NOT NULL"`
Enabled bool `xorm:"NOT NULL DEFAULT true"`
AutoReview bool `xorm:"NOT NULL DEFAULT true"`
Strictness string `xorm:"VARCHAR(20) NOT NULL DEFAULT 'standard'"`
IgnorePatterns string `xorm:"TEXT"`
CreatedUnix timeutil.TimeStamp
UpdatedUnix timeutil.TimeStamp
}
// TableName returns the table name for RepoSetting.
func (RepoSetting) TableName() string {
return "ai_repo_setting"
}
// UsageLog records AI token usage per action.
type UsageLog struct {
ID int64 `xorm:"pk autoincr"`
OrgID int64 `xorm:"INDEX NOT NULL"`
RepoID int64 `xorm:"INDEX NOT NULL"`
TriggeredByID int64
ActionType string `xorm:"VARCHAR(20) NOT NULL"` // review, chat, agent
Model string `xorm:"VARCHAR(50)"`
TokensInput int64
TokensOutput int64
DurationMs int64
CreatedUnix timeutil.TimeStamp `xorm:"INDEX"`
}
// TableName returns the table name for UsageLog.
func (UsageLog) TableName() string {
return "ai_usage_log"
}
// GetOrgSetting returns the AI settings for an org, or nil if not configured.
func GetOrgSetting(ctx context.Context, orgID int64) (*OrgSetting, error) {
setting := &OrgSetting{OrgID: orgID}
has, err := db.GetEngine(ctx).Where("org_id = ?", orgID).Get(setting)
if err != nil {
return nil, err
}
if !has {
return nil, nil
}
return setting, nil
}
// GetRepoSetting returns the AI settings for a repo, or nil if not configured.
func GetRepoSetting(ctx context.Context, repoID int64) (*RepoSetting, error) {
setting := &RepoSetting{RepoID: repoID}
has, err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Get(setting)
if err != nil {
return nil, err
}
if !has {
return nil, nil
}
return setting, nil
}
// CreateOrgSetting inserts a new org AI setting.
func CreateOrgSetting(ctx context.Context, setting *OrgSetting) error {
setting.CreatedUnix = timeutil.TimeStampNow()
setting.UpdatedUnix = timeutil.TimeStampNow()
_, err := db.GetEngine(ctx).Insert(setting)
return err
}
// UpdateOrgSetting updates an existing org AI setting.
func UpdateOrgSetting(ctx context.Context, setting *OrgSetting) error {
setting.UpdatedUnix = timeutil.TimeStampNow()
_, err := db.GetEngine(ctx).ID(setting.ID).AllCols().Update(setting)
return err
}
// CreateRepoSetting inserts a new repo AI setting.
func CreateRepoSetting(ctx context.Context, setting *RepoSetting) error {
setting.CreatedUnix = timeutil.TimeStampNow()
setting.UpdatedUnix = timeutil.TimeStampNow()
_, err := db.GetEngine(ctx).Insert(setting)
return err
}
// UpdateRepoSetting updates an existing repo AI setting.
func UpdateRepoSetting(ctx context.Context, setting *RepoSetting) error {
setting.UpdatedUnix = timeutil.TimeStampNow()
_, err := db.GetEngine(ctx).ID(setting.ID).AllCols().Update(setting)
return err
}
// LogUsage records an AI usage event.
func LogUsage(ctx context.Context, log *UsageLog) error {
log.CreatedUnix = timeutil.TimeStampNow()
_, err := db.GetEngine(ctx).Insert(log)
return err
}