-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathBlogWriterSessionService.cs
More file actions
81 lines (71 loc) · 2.97 KB
/
Copy pathBlogWriterSessionService.cs
File metadata and controls
81 lines (71 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
namespace BlogWriter;
public sealed class BlogWriterSessionService(
IBlogWorkflow workflow,
IBlogSessionStore sessionStore) : IBlogWriterSessionService
{
private readonly IBlogWorkflow _workflow = workflow;
private readonly IBlogSessionStore _sessionStore = sessionStore;
public async Task<BlogSession> StartAsync(
string prompt,
int minWords = ResearchState.DefaultMinWords,
int maxWords = ResearchState.DefaultMaxWords,
CancellationToken cancellationToken = default,
IProgress<WorkflowOutputUpdate>? output = null)
{
ArgumentException.ThrowIfNullOrWhiteSpace(prompt);
WordRange range = WordRange.Create(minWords, maxWords);
BlogSession session = await _sessionStore.CreateAsync(new ResearchState
{
MainTask = prompt.Trim(),
MinWords = range.Min,
MaxWords = range.Max,
}, cancellationToken);
session.State = await _workflow.RunAsync(session.State, cancellationToken, output);
await _sessionStore.SaveAsync(session, cancellationToken);
return session;
}
public async Task<BlogSession> ReviseAsync(
BlogSession session,
string revision,
int minWords,
int maxWords,
CancellationToken cancellationToken = default,
IProgress<WorkflowOutputUpdate>? output = null)
{
ArgumentNullException.ThrowIfNull(session);
ArgumentException.ThrowIfNullOrWhiteSpace(revision);
WordRange range = WordRange.Create(minWords, maxWords);
var candidate = new BlogSession
{
Id = session.Id,
OwnerId = session.OwnerId,
ETag = session.ETag,
CreatedAt = session.CreatedAt,
UpdatedAt = session.UpdatedAt,
State = Clone(session.State),
};
candidate.State.MinWords = range.Min;
candidate.State.MaxWords = range.Max;
candidate.State.StartFollowUp(revision);
candidate.State = await _workflow.RunAsync(candidate.State, cancellationToken, output);
await _sessionStore.SaveAsync(candidate, cancellationToken);
return candidate;
}
public Task<IReadOnlyList<BlogSessionSummary>> ListAsync(CancellationToken cancellationToken = default) =>
_sessionStore.ListAsync(cancellationToken);
public Task<BlogSession?> LoadAsync(string sessionId, CancellationToken cancellationToken = default) =>
_sessionStore.GetAsync(sessionId, cancellationToken);
private static ResearchState Clone(ResearchState source) => new()
{
MainTask = source.MainTask,
MinWords = source.MinWords,
MaxWords = source.MaxWords,
ResearchFindings = [.. source.ResearchFindings],
SearchRefinements = [.. source.SearchRefinements],
Draft = source.Draft,
ReviewNotes = source.ReviewNotes,
RevisionNumber = source.RevisionNumber,
NextStep = source.NextStep,
CurrentSubTask = source.CurrentSubTask,
};
}