Skip to content

Commit 06b4fe3

Browse files
committed
Allow deleting files when deleting vector store
When testing out vector store capabilities, it can be quite convenient to get rid of the files that were added to test the vector store itself. This can now be done with the `--files` switch.
1 parent a70e7f8 commit 06b4fe3

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using Spectre.Console;
2+
using Spectre.Console.Rendering;
3+
4+
namespace Devlooped.OpenAI;
5+
6+
public class PrefixProgressColumn(ProgressColumn inner, string prefix) : ProgressColumn
7+
{
8+
public override IRenderable Render(RenderOptions options, ProgressTask task, TimeSpan deltaTime)
9+
{
10+
var progress = inner.Render(options, task, deltaTime);
11+
return new Columns([new Markup(prefix), progress]);
12+
}
13+
}

src/dotnet-openai/Vectors/DeleteCommand.cs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,54 @@
33
using OpenAI;
44
using Spectre.Console;
55
using Spectre.Console.Cli;
6+
using static Devlooped.OpenAI.Vectors.DeleteCommand;
67

78
namespace Devlooped.OpenAI.Vectors;
89

910
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
1011
[Description("Delete a vector store by ID or name.")]
1112
[Service]
12-
public class DeleteCommand(OpenAIClient oai, IAnsiConsole console, VectorIdMapper mapper, CancellationTokenSource cts) : Command<StoreCommandSettings>
13+
public class DeleteCommand(OpenAIClient oai, IAnsiConsole console, VectorIdMapper mapper, CancellationTokenSource cts) : AsyncCommand<DeleteSettings>
1314
{
14-
public override int Execute(CommandContext context, StoreCommandSettings settings)
15+
public override async Task<int> ExecuteAsync(CommandContext context, DeleteSettings settings)
1516
{
17+
// Whether we need to delete all files too.
18+
if (settings.Files)
19+
{
20+
if (App.IsNonInteractive)
21+
{
22+
await Parallel.ForEachAsync(oai.GetVectorStoreClient().GetFileAssociationsAsync(settings.Store, cancellationToken: cts.Token), cts.Token,
23+
async (file, token) => await oai.GetOpenAIFileClient().DeleteFileAsync(file.FileId, cancellationToken: token));
24+
}
25+
else
26+
{
27+
await console.Progress()
28+
.Columns(
29+
[
30+
new TaskDescriptionColumn(),
31+
new ProgressBarColumn(),
32+
new PercentageColumn(),
33+
new PrefixProgressColumn(new RemainingTimeColumn(), Emoji.Known.HourglassNotDone),
34+
new PrefixProgressColumn(new ElapsedTimeColumn(), Emoji.Known.HourglassDone),
35+
])
36+
.StartAsync(async ctx =>
37+
{
38+
var task = ctx.AddTask($"Deleting files associated with {settings.Store}");
39+
task.MaxValue(oai.GetVectorStoreClient().GetVectorStore(settings.Store, cts.Token).Value.FileCounts.Total);
40+
await Parallel.ForEachAsync(oai.GetVectorStoreClient().GetFileAssociationsAsync(settings.Store, cancellationToken: cts.Token), cts.Token,
41+
async (file, token) =>
42+
{
43+
await oai.GetOpenAIFileClient().DeleteFileAsync(file.FileId, cancellationToken: token);
44+
lock (task)
45+
{
46+
task.Description($"Deleting {task.Value + 1} of {task.MaxValue} files associated with {settings.Store}");
47+
task.Increment(1);
48+
}
49+
});
50+
});
51+
}
52+
}
53+
1654
var response = oai.GetVectorStoreClient().DeleteVectorStore(settings.Store, cts.Token);
1755
var json = response.GetRawResponse();
1856

@@ -35,4 +73,11 @@ public override int Execute(CommandContext context, StoreCommandSettings setting
3573
return 0;
3674
}
3775
}
76+
77+
public class DeleteSettings(VectorIdMapper mapper) : StoreCommandSettings(mapper)
78+
{
79+
[Description("Delete files associated with the vector store too.")]
80+
[CommandOption("--files")]
81+
public bool Files { get; set; }
82+
}
3883
}

0 commit comments

Comments
 (0)