Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions apiclient/types/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ package types
type Project struct {
Metadata
ProjectManifest
AssistantID string `json:"assistantID,omitempty"`
Editor bool `json:"editor"`
ParentID string `json:"parentID,omitempty"`
SourceProjectID string `json:"sourceProjectID,omitempty"`
UserID string `json:"userID,omitempty"`
WorkflowNamesFromIntegration WorkflowNamesFromIntegration `json:"workflowNamesFromIntegration,omitempty"`
TemplateUpgradeAvailable bool `json:"templateUpgradeAvailable,omitempty"`
TemplateUpgradeInProgress bool `json:"templateUpgradeInProgress,omitempty"`
TemplateLastUpgraded *Time `json:"templateLastUpgraded,omitempty"`
TemplatePublicID string `json:"templatePublicID,omitempty"`
AssistantID string `json:"assistantID,omitempty"`
Editor bool `json:"editor"`
ParentID string `json:"parentID,omitempty"`
SourceProjectID string `json:"sourceProjectID,omitempty"`
UserID string `json:"userID,omitempty"`
WorkflowNamesFromIntegration WorkflowNamesFromIntegration `json:"workflowNamesFromIntegration,omitempty"`
TemplateUpgradeAvailable bool `json:"templateUpgradeAvailable,omitempty"`
TemplateForceUpgradeAvailable bool `json:"templateForceUpgradeAvailable,omitempty"`
TemplateUpgradeInProgress bool `json:"templateUpgradeInProgress,omitempty"`
TemplateLastUpgraded *Time `json:"templateLastUpgraded,omitempty"`
TemplatePublicID string `json:"templatePublicID,omitempty"`
}

type WorkflowNamesFromIntegration struct {
Expand Down
26 changes: 10 additions & 16 deletions pkg/api/handlers/projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,6 @@ func (h *ProjectsHandler) UpgradeFromTemplate(req api.Context) error {
return types.NewErrHTTP(http.StatusTooEarly, "project upgrade already in progress")
}

if !thread.Status.UpgradeAvailable {
// Project is ineligable for an upgrade due to one of the following reasons:
// - the project is already at the latest revision of the project snapshot
// - the user has manually modified the project
return types.NewErrBadRequest("project not eligible for an upgrade")
}

if thread.Spec.UpgradeApproved {
// Project is already approved for an upgrade, nothing to do
return nil
Expand Down Expand Up @@ -518,15 +511,16 @@ func convertProject(thread *v1.Thread, parentThread *v1.Thread) types.Project {
Models: thread.Spec.Models,
Capabilities: convertProjectCapabilities(thread.Spec.Capabilities),
},
ParentID: strings.Replace(thread.Spec.ParentThreadName, system.ThreadPrefix, system.ProjectPrefix, 1),
SourceProjectID: strings.Replace(thread.Spec.SourceThreadName, system.ThreadPrefix, system.ProjectPrefix, 1),
AssistantID: thread.Spec.AgentName,
Editor: thread.IsEditor(),
UserID: thread.Spec.UserID,
WorkflowNamesFromIntegration: thread.Status.WorkflowNamesFromIntegration,
TemplateUpgradeAvailable: (thread.Status.UpgradeAvailable && !thread.Spec.UpgradeApproved),
TemplateUpgradeInProgress: thread.Status.UpgradeInProgress,
TemplatePublicID: thread.Status.UpgradePublicID,
ParentID: strings.Replace(thread.Spec.ParentThreadName, system.ThreadPrefix, system.ProjectPrefix, 1),
SourceProjectID: strings.Replace(thread.Spec.SourceThreadName, system.ThreadPrefix, system.ProjectPrefix, 1),
AssistantID: thread.Spec.AgentName,
Editor: thread.IsEditor(),
UserID: thread.Spec.UserID,
WorkflowNamesFromIntegration: thread.Status.WorkflowNamesFromIntegration,
TemplateUpgradeAvailable: (thread.Status.UpgradeAvailable && !thread.Spec.UpgradeApproved),
TemplateForceUpgradeAvailable: thread.Status.ForceUpgradeAvailable,
TemplateUpgradeInProgress: thread.Status.UpgradeInProgress,
TemplatePublicID: thread.Status.UpgradePublicID,
}

if !thread.Status.LastUpgraded.IsZero() {
Expand Down
11 changes: 8 additions & 3 deletions pkg/controller/handlers/threads/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ func (t *Handler) EnsureUpgradeAvailable(req router.Request, _ router.Response)
}

var (
source v1.Thread
upgradeAvailable bool
source v1.Thread
upgradeAvailable bool
forceUpgradeAvailable bool
)
if err := req.Client.Get(req.Ctx, router.Key(thread.Namespace, thread.Spec.SourceThreadName), &source); err != nil {
if !apierrors.IsNotFound(err) {
Expand All @@ -53,18 +54,22 @@ func (t *Handler) EnsureUpgradeAvailable(req router.Request, _ router.Response)
// If we find the revision, but it's the latest revision, there's no new upgrade available.
found, latest := source.HasRevision(thread.GetLatestConfigRevision())
upgradeAvailable = found && !latest

// if the thread's latest revision is not in the source thread's history, then we provide a status to show option to force upgrade
forceUpgradeAvailable = !found
}

upgradeAvailable = !source.Status.UpgradeInProgress && upgradeAvailable
}

if thread.Status.UpgradeAvailable == upgradeAvailable {
if thread.Status.UpgradeAvailable == upgradeAvailable && thread.Status.ForceUpgradeAvailable == forceUpgradeAvailable {
// No change, bail out
return nil
}

// Update the status with the new value
thread.Status.UpgradeAvailable = upgradeAvailable
thread.Status.ForceUpgradeAvailable = forceUpgradeAvailable
return req.Client.Status().Update(req.Ctx, thread)
}

Expand Down
3 changes: 3 additions & 0 deletions pkg/storage/apis/obot.obot.ai/v1/thread.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,9 @@ type ThreadStatus struct {
// into this thread AND the thread's configuration has not changed since it was copied.
UpgradeAvailable bool `json:"upgradeAvailable,omitempty"`

// ForceUpgradeAvailable is a flag to indicate if an force upgrade is available from the source thread.
ForceUpgradeAvailable bool `json:"forceUpgradeAvailable,omitempty"`

// UpgradeInProgress indicates if an upgrade from the source thread is in progress.
UpgradeInProgress bool `json:"upgradeInProgress,omitempty"`

Expand Down
13 changes: 13 additions & 0 deletions pkg/storage/openapi/generated/openapi_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 34 additions & 12 deletions ui/user/src/lib/components/edit/ProjectConfiguration.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { closeAll, getLayout } from '$lib/context/chatLayout.svelte';
import { ChatService, type Project } from '$lib/services';
import { LoaderCircle, X, AlertCircle, CircleFadingArrowUp } from 'lucide-svelte';
import { LoaderCircle, X, CircleFadingArrowUp } from 'lucide-svelte';
import { HELPER_TEXTS } from '$lib/context/helperMode.svelte';
import Memories from '$lib/components/edit/Memories.svelte';
import { getProjectTools } from '$lib/context/projectTools.svelte';
Expand Down Expand Up @@ -41,6 +41,12 @@
project.templateUpgradeAvailable &&
shareUrl
);
let showForceUpgradeButton = $derived(
!!project?.sourceProjectID &&
project.sourceProjectID.trim() !== '' &&
project.templateForceUpgradeAvailable &&
shareUrl
);

async function upgradeFromTemplate() {
upgradeLoading = true;
Expand Down Expand Up @@ -166,21 +172,37 @@
<CircleFadingArrowUp class="relative top-[1px] size-4 shrink-0" />
{/if}
</button>
{:else if showForceUpgradeButton}
<button
class="button flex gap-1"
onclick={upgradeFromTemplate}
disabled={upgradeLoading}
title="This will override any manual changes and upgrade to the latest revision"
>
{#if upgradeLoading}
<LoaderCircle class="size-4 animate-spin" />
{:else}
Force Upgrade
<CircleFadingArrowUp class="relative top-[1px] size-4 shrink-0" />
{/if}
</button>
{/if}
</div>
</div>
{/if}

<p
class="mt-1 flex w-full items-center justify-center gap-1 text-center text-xs font-light text-gray-600"
>
<AlertCircle class="max-h-3.5 min-h-3.5" />
<span>
Changing fields such as instructions, MCP servers, tasks, or knowledge will make
this project ineligible to receive updates from the shared project snapshot
author.
</span>
</p>
{#if showForceUpgradeButton}
<p
class="mt-2 flex w-full items-center justify-center gap-1 text-center text-xs font-light text-yellow-500"
>
<AlertTriangle class="max-h-3.5 min-h-3.5" />
<span>
Our system has detected that you have made changes to this project that are
launched from a template. Clicking on Force Upgrade will override any changes
that were made manually and upgrade to the latest revision of the original
project template.
</span>
</p>
{/if}
</div>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions ui/user/src/lib/services/chat/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ export interface Project {
userID: string;
workflowNamesFromIntegration?: WorkflowNamesFromIntegration;
templateUpgradeAvailable?: boolean;
templateForceUpgradeAvailable?: boolean;
templateUpgradeInProgress?: boolean;
templateLastUpgraded?: string;
templatePublicID?: string;
Expand Down