-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cache ask results in db #337
Conversation
Southclaws
commented
Dec 30, 2024
- key based on question, slugified
- future work: vector lookup with tight threshold
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 2 Skipped Deployments
|
📝 WalkthroughWalkthroughThe pull request introduces a comprehensive implementation of a new Changes
Sequence DiagramsequenceDiagram
participant User
participant Asker
participant QuestionRepo
participant Database
User->>Asker: Ask a question
Asker->>QuestionRepo: Check for cached result
alt Cached result exists
QuestionRepo-->>Asker: Return cached result
else No cached result
Asker->>Asker: Generate live prompt
Asker->>QuestionRepo: Store new question
QuestionRepo->>Database: Save question
Asker-->>User: Stream response
end
Possibly related PRs
Poem
Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (19)
app/services/semdex/asker/asker.go (3)
27-42
: InitializeAsker
fields with parameter validation
It's good to see theAsker
struct being constructed with all relevant dependencies. However, consider validating thatquestions
andlogger
are non-nil to avoid potential nil-pointer dereferences in subsequent methods.
79-101
: Prevent potential race condition incachedResult
Because this function streams chunks with a sleep, if the same question is processed simultaneously in different goroutines, concurrency issues could arise ifq.Result.HTMLTree()
is updated or replaced. Ensure the underlying data is immutable or guarded with locks if shared by multiple goroutines.
179-192
: Validate maximum length constraints before caching
cacheResult
stores the entire result in the database. If the result is excessively large, it could cause performance bottlenecks or exceed DB column size limits, depending on the schema. Adding an upper limit check, perhaps configured incfg
, can help maintain reliability.internal/ent/question_create.go (4)
74-79
: Metadata type consistency
TheSetMetadata
method relies onmap[string]interface{}
. Ensure that callers maintain consistent typing within this map, or consider a typed struct if usage patterns are known. This helps avoid runtime errors when encoding/decoding the JSON field.
156-182
: Field validation incheck()
The validations for required fields (slug, query, result, etc.) are clear. However, consider adding context about what caused the failure in error messages, e.g., including the faulty value or more details on constraints. This can ease debugging in large systems.
190-194
: Handle MySQL constraint errors with more detail
Whensqlgraph.CreateNode
fails due to constraint violations, you wrap it inConstraintError
. Providing more detail (e.g., which field caused the violation) could make troubleshooting easier.
581-643
: Bulk creation approach
The bulk creation logic carefully sets defaults for each builder. If partial failures occur within the batch, the entire batch might fail. Consider whether a partial success strategy is needed or if an all-or-nothing design is acceptable.app/resources/question/question.go (1)
34-41
: Potential Null Reference inin.Result
While this code checks for errors during the conversion, consider verifying that
in.Result
is never empty or null. This could avoid potential edge cases for partially saved data.app/resources/question/repo.go (1)
57-71
: Fetching by ID with Author and Role RelationshipThis ensures you return a fully hydrated
Question
object. Any usage of partial or subset queries could speed up performance if the entire dataset isn’t always needed, but that’s optional.internal/ent/question.go (2)
129-136
: Consider advanced error logging for JSON unmarshalling.
When decodingMetadata
in lines 129–136, any JSON unmarshal error is reported. For better debugging, you might consider including more context (like which record ID was being processed) so troubleshooting becomes easier.
178-207
: Potential performance enhancement in building string representations.
When creating large strings in performance-critical scenarios, consider using a pre-allocated buffer or advanced string concatenation methods if performance becomes a bottleneck. Currently, the builder usage is fine for most cases.internal/ent/question_update.go (3)
48-52
: Be aware of potential null impact on indexing logic.Clearing the "indexed_at" field removes existing indexing timestamps from the record. If other systems rely on a non-null timestamp, this may cause confusion. Ensure downstream consumers handle null
indexed_at
properly.
218-230
: Clarify author edge clearance behavior.Clearing the required unique edge "author" raises an error if it’s immediately re-set in the same mutation. If the design intent is to optionally remove the
author
link, validate both the business logic and user flows to avoid accidental “author” loss.
249-255
: Enhance constraint error messaging.When a constraint error occurs, consider appending more context (like the specific field or edge) to facilitate faster debugging, rather than returning only the generic “constraint failed” message.
internal/ent/question/where.go (1)
169-172
: Use caution with nil checks on "indexed_at".While
IndexedAtIsNil()
is useful for discovering unindexed questions, confirm that the caching mechanism correctly interprets unindexed questions and reindexes them when appropriate.internal/ent/account.go (2)
70-71
: Consider lazy loading or pagination forQuestions
.If the number of linked questions grows significantly, returning them all at once could impact performance. Evaluate if lazy loading or pagination might be beneficial.
96-96
: Incrementing loadedTypes size.Remember to update any logic that relies on
loadedTypes
array indexing if additional edges are added in the future. Off-by-one errors are easy to miss in array expansions.internal/ent/question_query.go (1)
410-419
: Consider Bulk Loading OptimizationsThe
loadAuthor
method individually aggregates questions byaccount_id
. If large volumes of data are expected, ensure that the current approach scales and consider potential optimizations (e.g., batching or more specialized queries) if performance becomes an issue.internal/ent/account/where.go (1)
794-805
: Conditional Filtering with Predicates
HasQuestionsWith
allows additional conditions on the joined table, enabling richer queries. Useful for scoping queries by question properties.Consider adding unit tests or integration tests that illustrate advanced usage combining multiple
predicate.Question
conditions.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
go.mod
is excluded by!**/*.mod
go.sum
is excluded by!**/*.sum
,!**/*.sum
📒 Files selected for processing (32)
app/resources/datagraph/content.go
(2 hunks)app/resources/datagraph/content_test.go
(1 hunks)app/resources/question/question.go
(1 hunks)app/resources/question/repo.go
(1 hunks)app/resources/resources.go
(2 hunks)app/services/semdex/asker/asker.go
(3 hunks)app/services/semdex/semdex.go
(1 hunks)app/transports/http/bindings/datagraph.go
(2 hunks)internal/ent/account.go
(14 hunks)internal/ent/account/account.go
(4 hunks)internal/ent/account/where.go
(1 hunks)internal/ent/account_create.go
(3 hunks)internal/ent/account_query.go
(9 hunks)internal/ent/account_update.go
(7 hunks)internal/ent/client.go
(11 hunks)internal/ent/ent.go
(2 hunks)internal/ent/er.html
(2 hunks)internal/ent/hook/hook.go
(1 hunks)internal/ent/migrate/schema.go
(3 hunks)internal/ent/mutation.go
(15 hunks)internal/ent/predicate/predicate.go
(1 hunks)internal/ent/question.go
(1 hunks)internal/ent/question/question.go
(1 hunks)internal/ent/question/where.go
(1 hunks)internal/ent/question_create.go
(1 hunks)internal/ent/question_delete.go
(1 hunks)internal/ent/question_query.go
(1 hunks)internal/ent/question_update.go
(1 hunks)internal/ent/runtime.go
(2 hunks)internal/ent/schema/account.go
(1 hunks)internal/ent/schema/question.go
(1 hunks)internal/ent/tx.go
(2 hunks)
🔇 Additional comments (121)
app/services/semdex/asker/asker.go (2)
70-77
: Verify presence of questions
repository
When err == nil
, the flow assumes cached
is not nil, but if questions
or the cached entity unexpectedly is nil, it could lead to a panic later. Consider adding a quick nil check on cached
.
103-151
: 🛠️ Refactor suggestion
Clean resource usage on stream termination
The livePrompt
method uses two channels for streaming data and errors. The cleanup logic is invoked when the chunk channel is closed or if yield
returns false, which is good. However, consider handling the scenario where ech
immediately returns an error but chch
doesn’t close. You might need an extra wait or channel drain to prevent potential goroutine leaks.
app/transports/http/bindings/datagraph.go (2)
62-65
: Return immediate error on Ask
failure
The direct check for err
after d.asker.Ask(ctx, query)
is appropriate. This ensures that downstream logic is not executed if the Asker
initialization fails. The error wrapping is also good here.
79-89
: Graceful partial response handling
When streaming the chunks with the new iterator approach, returning err
immediately ends the response. If you want partial results to be kept, consider buffering them until the stream completes or fails. Currently, partial data is written, but subsequent logic stops if an error is encountered. This behavior might be acceptable but is worth confirming against product requirements.
internal/ent/question_create.go (1)
20-30
: Ensure concurrency safety when reusing QuestionCreate
QuestionCreate
holds a mutation
struct that might still have state if reused concurrently. If multiple goroutines call SetCreatedAt
and others, it may cause undefined behavior. Typically, builders like QuestionCreate
are used once per entity creation.
internal/ent/mutation.go (15)
34-34
: Import for Question entity looks good.
No issues found with the added import; it aligns with the new Question references in the code.
71-71
: New TypeQuestion constant is consistent.
The newly introduced TypeQuestion = "Question"
matches the naming convention for other entity types.
119-121
: New fields for questions in AccountMutation are consistent.
These fields (questions
, removedquestions
, clearedquestions
) match the existing pattern for other edges like posts
and reacts
.
1159-1212
: Edge methods for "questions" are well-structured.
All methods (Add, Remove, Clear, Reset, etc.) follow the same design used for other edges, ensuring consistent behavior.
[approve]
Consider adding tests or verifying usage to confirm these methods correctly integrate with the rest of the codebase.
2149-2149
: Maintainable fixed-capacity slice initialization.
Using make([]string, 0, 20)
is fine and follows the existing approach.
2174-2176
: AddedEdges logic for questions is appropriate.
Including account.EdgeQuestions
in added edges ensures the correct handling of newly set relationships.
2263-2268
: Retrieving IDs for added questions is consistent.
Collecting IDs from m.questions
matches the established approach for other edges.
2341-2341
: RemovedEdges slice initialization is consistent.
Same approach as for added edges; no issues found.
2363-2365
: RemovedEdges logic for questions is correct.
Appending account.EdgeQuestions
when m.removedquestions
is not nil is consistent with other edges.
2448-2453
: RemovedIDs method for questions is well-implemented.
Gathering IDs from m.removedquestions
aligns with the ent mutation pattern.
2526-2526
: ClearedEdges uses a fixed-cap slice.
Continuing the existing pattern for edges capacity is acceptable.
2551-2553
: ClearedEdges logic for "questions" is solid.
Conditionally adding account.EdgeQuestions
allows consistent clearing detection.
2610-2611
: EdgeCleared method extended for questions.
Returning m.clearedquestions
ensures consistent reporting for the "questions" edge.
2677-2679
: Edge reset for questions is consistent.
Invoking m.ResetQuestions()
properly reverts changes to the "questions" edge.
20320-21083
: Comprehensive QuestionMutation logic is well-aligned with Ent conventions.
This large block defines a thorough set of mutation methods for the new Question
entity—covering fields, relationships, and old-value lookups. The approach is consistent with Ent’s design, and no critical issues stand out.
internal/ent/schema/question.go (4)
1-2
: File Header Looks Good
This file header and package declaration follow common Go conventions for ent schema files.
14-16
: Mixins Properly Declared
Using Identifier
, CreatedAt
, and IndexedAt
mixins keeps the schema DRY and consistent with any existing patterns or shared fields.
18-28
: Ensure metadata
Field Handles Valid JSON
The optional JSON field for metadata
is useful for arbitrary data. Ensure that there's validation logic (or usage guidelines) to prevent malformed JSON data.
Would you like a script to scan usage of metadata
, ensuring correct JSON usage or any validation presence in the codebase?
30-38
: Edges Configuration Aligns with account_id
The edge from author
verifies the relationship to Account
, marking it as unique and required. This should keep the schema consistent, though confirm that this edge is never left unset during entity creation.
app/resources/question/question.go (5)
1-2
: Package Declaration and Imports
All required imports for the question
package seem properly declared, aligning with the new Question
structure and mapping logic.
10-16
: Struct Fields Are Comprehensive
The Question
struct includes Slug
, Query
, Result
, Author
and an ID
field. This matches the ent schema, ensuring data consistency across layers.
18-22
: Edge Retrieval Error Handling
Error checking on Edges.AuthorOrErr()
is a good practice to avoid nil references. Ensuring that the author is present in the DB is crucial.
24-27
: Result Field Conversion
Wrapping datagraph.NewRichText(in.Result)
with error handling is valuable to ensure no invalid or malformed content breaks the application.
29-32
: Author Mapping Logic
Mapping the linked author entity ensures that the returned author
object is the same structure used elsewhere, maintaining consistency.
app/resources/question/repo.go (5)
24-27
: Constructing and Mutating the Question
Good approach in combining create.Mutation()
on the same chain. This ensures code readability and future maintainability.
28-29
: Slug Generation from Query
slug.Make(query)
is appropriate for generating a consistent slug; ensure edge cases like empty or extremely long queries are handled gracefully.
35-35
: Conflict Resolution Strategy - “slug”
OnConflictColumns("slug").UpdateNewValues()
indicates upsert logic. Confirm that overwriting is the intended behavior to avoid unintentionally overwriting existing data.
42-55
: Retrieving and Mapping the Saved Entity
Fetching the newly saved question and mapping is a good pattern to return a complete object. Confirm that all edges are loaded if there's the possibility of more linked data in future expansions.
73-89
: Slug-based Retrieval Method
GetByQuerySlug
is consistent with how Store
derives a slug. Keep an eye on collisions if users submit identical queries.
internal/ent/predicate/predicate.go (1)
66-68
: New Question Predicate
Having type Question func(*sql.Selector)
aligns with ent’s approach to filtering. This is a straightforward addition to support question-specific queries.
internal/ent/schema/account.go (1)
66-66
: Good job adding the questions
edge to the Account
entity.
This new relationship expands the data model to link an account with multiple questions. Ensure that your client code handles any potential cascading operations (e.g., whether to automatically delete questions when an account is deleted) in a way that aligns with your business requirements.
internal/ent/question_delete.go (9)
15-20
: The QuestionDelete
struct correctly follows Ent patterns.
It encapsulates the configuration, hooks, and mutation needed to manage deletions. This approach provides a clear structure to build on for future custom logic.
23-26
: The Where
method is properly appending predicates.
This ensures flexible filtering of Question
entities during deletion. Nicely done following Ent’s builder pattern.
28-31
: Appropriate hooking of the deletion execution.
Wrapping the execution with hooks allows customized pre- or post-deletion behavior. This pattern is consistent with Ent best practices.
33-40
: The ExecX
method’s panic-on-error approach is used appropriately.
It offers a concise way to handle failures by deferring error handling to caller functions or higher-level panic recoveries.
42-57
: sqlExec
is well-structured for the low-level deletion logic.
Careful handling of constraints by wrapping them into ConstraintError
ensures maintainable error handling. Marking mutation.done = true
is important to ensure the builder can’t be reused.
60-62
: The QuestionDeleteOne
struct nicely embeds QuestionDelete
.
This design reuses the existing deletion logic for single-entity deletes, avoiding duplicate code.
65-68
: Where
method on QuestionDeleteOne
consistently re-applies the shared mutation logic.
This adds a straightforward predicate layering for single-entity deletion.
70-81
: The Exec
method elegantly handles the “no row found” scenario.
Returning a NotFoundError
provides a clear contract for callers, ensuring robust error handling when no entity matches the criteria.
83-88
: The ExecX
method’s panic-on-error usage is consistent.
As with the multi-entity deletion, this design is suitable when the caller is prepared to handle panics.
app/resources/resources.go (2)
46-46
: Importing the question
package extends resource loading.
This import ensures the new Question resource is available within the application’s dependency injection framework.
98-98
: Registering the question.New
constructor is consistent with the pattern used for other resources.
It fully integrates the Question
resource into the FX lifecycle. Good job maintaining uniformity across resource registrations.
internal/ent/question/question.go (14)
1-2
: Auto-generated Ent file successfully created for the question
package.
These headers signify that changes will be overwritten when regenerating code from the schema. Maintain any custom changes in separate extension files or custom hooks, if necessary.
3-12
: Package structure correctly imports necessary modules for question
.
Time, SQL, and sqlgraph
are essential for definitions, while github.com/rs/xid
is used for ID generation. Everything looks consistent with Ent patterns.
13-43
: Constants defining the question
schema are well organized.
They cover field names, edge names, and table names. This ensures consistent references across your codebase.
45-65
: Columns
and ValidColumn
elegantly manage valid fields.
Mapping the schema fields into a slice and verifying against it adds safety for dynamic queries. Good job ensuring robust field validation.
67-74
: Default field functions and validators are well structured.
They allow custom initialization logic (e.g., generating xid.ID
) and validation prior to saving the entity.
76-78
: OrderOption
type definition is standard for Ent ordering.
This approach offers a flexible way to chain ordering logic without duplicating code throughout your queries.
79-82
: ByID
ordering function is properly implemented.
It uses sql.OrderByField
to produce an OrderOption
—a typical Ent pattern for custom or field-based ordering.
84-87
: ByCreatedAt
ordering function follows the same structure.
The approach ensures consistent ordering capabilities across various data fields.
89-92
: ByIndexedAt
extends the same ordering logic.
It’s clear this method remains consistent with the rest.
94-97
: BySlug
ordering function is straightforward.
Follows the established pattern for ordering queries on the slug
field.
99-102
: ByQuery
ordering function ensures sorting by the question text.
Maintaining uniform naming conventions for clarity is good practice.
104-107
: ByResult
ordering function for sorting on result content.
This helps when retrieving questions sorted by processed output or appended content.
109-112
: ByAccountID
ordering provides easy grouping by account associations.
This is consistent with the new edge linking accounts to questions.
114-126
: ByAuthorField
leverages sqlgraph.OrderByNeighborTerms
for M2O relationship ordering.
The separate newAuthorStep
function keeps the logic clean and helps avoid duplication. Good job structuring neighbor-based ordering carefully.
internal/ent/question.go (1)
18-50
: The generated code approach looks solid.
This entire entity file is automatically generated by Ent. Typically, we avoid manually editing these files to prevent losing changes on the next code generation. The new fields (Slug, Query, etc.) and the edges (author) appear consistent with the standard Ent patterns.
internal/ent/tx.go (1)
55-56
: Integration of QuestionClient is correct and consistent.
The new Question *QuestionClient
field is initialized in init()
. This ensures the transactional context is extended to the new entity. It aligns with standard Ent patterns, so it looks good.
Also applies to: 215-215
internal/ent/hook/hook.go (1)
240-250
: Proper handling of QuestionMutation in hooks.
The new QuestionFunc
and its Mutate
method correctly follow the established pattern of type checking mutation objects. This ensures that mutation logic applies specifically to the Question
entity.
app/resources/datagraph/content_test.go (1)
129-159
: Test coverage for Markdown-based content creation is solid.
The new TestNewRichTextFromMarkdown
properly verifies generating short text, references, and rendered HTML. This helps ensure the content transformation logic behaves as expected.
internal/ent/question_update.go (2)
20-32
: Consider further validation for predicates when chaining multiple updates.
Although the Where
function is flexible, ensure that complex filtering logic does not accidentally exclude rows meant to be updated or vice versa. You may want to add additional validation or logging for scenarios where unintuitive predicates are combined.
108-112
: Validate the presence of an account before assigning account ID.
When setting account_id
, confirm the ID actually references a valid account. This preemptive check helps prevent potential foreign key constraint errors.
internal/ent/ent.go (2)
34-34
: Ensure consistent grouping of imports.
The addition of "github.com/Southclaws/storyden/internal/ent/question"
is appropriate for referencing the question
entity. Validate your import ordering guidelines to keep imports organized and consistent across the project.
118-118
: Verify the correctness of added table validation.
Adding question.Table: question.ValidColumn
is a good measure to ensure column checks for the new entity. Confirm that all question columns are properly recognized by ValidColumn
.
internal/ent/question/where.go (2)
14-17
: Check ID filter usage for partial updates and caching.
IDs of type xid.ID
may have unique behaviors (e.g., collisions, case differences). Make sure the filter conditions align with the caching strategy, especially if the ID generation scheme interacts with question slug creation.
454-463
: Review the correctness of HasAuthor in M2O relations.
The HasAuthor()
predicate works as intended for one-to-many relationships, but if usage patterns expect more complex logic (e.g., user roles or multiple associations), validate that the logic still fits.
internal/ent/account.go (2)
173-180
: Ensure eager loading of questions for subsequent logic.
If subsequent logic depends on Questions
, ensure the edge is loaded before using QuestionsOrErr()
, or handle the NotLoadedError
gracefully. This particularly matters in scenarios where caching is involved.
445-448
: Maintain consistent naming convention for query methods.
QueryQuestions()
follows established naming patterns. Confirm that external references to this method (if any) align with the same naming approach for clarity across the codebase.
internal/ent/question_query.go (4)
20-32
: Robust Query Builder Implementation
The struct and field definitions, along with the initial setup of the query builder, are well-structured and align with Ent’s best practices. The approach of storing predicates, ordering conditions, and context in the QuestionQuery
fields provides clean extensibility.
87-98
: Graceful Handling of First
Query
Using Limit(1)
followed by handling an empty result set with a NotFoundError
is a standard pattern for retrieving a single entity safely. This approach is commendable.
178-185
: Cautious Use of Panics in X-Suffix Methods
The FirstIDX
and similar X-suffix methods (like OnlyX
, etc.) panic if an unexpected error occurs. While this is part of Ent’s generated code, confirm that the calling code handles these panics appropriately or that these methods are used sparsely in production to avoid unintended disruptions.
495-528
: Modifiers and Custom Selectors
The support for adding query modifiers and custom logic via Modify
is a flexible extension point. Ensure consistent usage across the codebase so that logic is centrally maintained and discoverable.
internal/ent/account/account.go (5)
56-57
: Clarity in Naming the "questions" Edge
Defining EdgeQuestions
for the new questions relationship is consistent with existing naming conventions. This edge name is clear and self-explanatory.
138-144
: Snapping to Existing Pattern
Introducing the QuestionsTable
, QuestionsInverseTable
, and QuestionsColumn
for the new relation aligns with existing ent naming conventions, reducing confusion for other maintainers.
432-437
: Order By Questions Count
ByQuestionsCount
is a neat addition that leverages sqlgraph.OrderByNeighborsCount
. Confirm thorough testing in real scenarios to ensure correct ordering when multiple edges exist.
439-444
: Ordering by Questions Terms
ByQuestions
appropriately delegates neighbor-based ordering to sqlgraph.OrderByNeighborTerms
. This provides more granular ordering for advanced queries.
655-661
: New Step for Questions Edge
newQuestionsStep()
is consistent with other edge step builders. The O2M edge definition correctly matches the intended one-to-many relationship between accounts and questions.
internal/ent/account/where.go (1)
783-792
: Simple Existence Check for Questions
HasQuestions
effectively checks for at least one related question. Ensure calling code interprets this correctly, especially in multi-filter logic.
internal/ent/migrate/schema.go (4)
694-704
: New Columns for “questions” Table
Defining id
, created_at
, indexed_at
, slug
, etc., provides a rich schema. The uniqueness constraint on slug
ensures queries can quickly find questions by a canonical string.
705-718
: Maintaining Relational Integrity
OnDelete: schema.NoAction
for the account_id
foreign key signals a strict requirement that an account must exist before referencing it in questions
. This can be ideal if desired, but double-check if a cascade or set-null policy might be more user-friendly for record cleanup.
1015-1015
: Inclusion in Global Tables Slice
Adding QuestionsTable
to the global Tables
array ensures the table is generated and managed by migrations. This is a pivotal step to fully integrate the new entity.
1069-1069
: Foreign Key Reference
QuestionsTable.ForeignKeys[0].RefTable = AccountsTable
properly links the question entity to its parent account. Verify the correct usage of schema.NoAction
on delete to avoid orphan references if accounts are removed.
internal/ent/runtime.go (2)
27-27
: Import for question package is correct.
The introduced import aligns with the new Question
entity.
801-831
: Properly initializing the Question
mixin.
The code follows the established pattern of reading mixin fields, setting defaults, and defining validators. This addition appears consistent with existing entities.
internal/ent/account_create.go (3)
29-29
: Import statement for question package confirmed.
Bringing in the question
package is necessary for referencing Question
entities.
291-305
: New methods for adding Question
entities.
The methods AddQuestionIDs
and AddQuestions
provide a straightforward way to associate Question
entities with an Account
. This is consistent with existing naming patterns.
761-776
: Edge specification for questions
during account creation.
The O2M relationship logic is consistent with the approach used for similar edges like posts
or emails
.
internal/ent/account_query.go (8)
30-30
: Import statement for question
aligned with the new edge.
This is needed to support the QueryQuestions
method.
52-52
: New field withQuestions
in AccountQuery
.
Enabling the eager-loading of Question
entities is consistent with other “with” patterns.
277-298
: QueryQuestions
method to traverse the questions edge.
Implements a typical O2M query flow. The step logic is correct for bridging from account
to question
.
741-741
: Clone logic for withQuestions
.
Retaining the cloned withQuestions
query ensures consistency in repeated query usage.
848-858
: Eager load approach via WithQuestions
.
Mirrors other With*
methods. Adhering to established design patterns in the codebase.
Line range hint 1058-1067
: Expanding loaded types array to 20.
Reflects adding a new “questions” relationship. This is important to track loaded edges.
1159-1165
: Loading logic for queried questions
.
The check ensures an empty slice is pre-initialized and appended when the withQuestions
sub-query is active.
1495-1524
: loadQuestions
for the O2M edge.
The usage of the foreign key AccountID
is consistent with other edge-loading patterns.
internal/ent/account_update.go (7)
30-30
: Import for question
package.
Required for referencing the new Question
entity and its schema definitions.
320-334
: Introducing AddQuestionIDs
& AddQuestions
in AccountUpdate
.
The logic parallels similar methods for other edges. Implementation is clean and consistent.
658-678
: Removal methods for the questions
edge.
Provides necessary operations to clear and remove Question
entities, mirroring standard design.
1370-1414
: Edge handling in sqlSave
for question fields.
The O2M setup for questions
is cohesive and well-aligned with the rest of the codebase.
2221-2235
: Methods for associating questions in AccountUpdateOne
.
Allows adding multiple Question
entities to a single Account
, matching the multi-add pattern used elsewhere.
2559-2579
: Removal methods for questions
in AccountUpdateOne
.
The approach to clearing and removing questions
is suitably consistent with other edges.
3301-3345
: O2M edge handling in sqlSave
for AccountUpdateOne
.
Covers add, remove, and clear operations for questions
. No issues noted.
internal/ent/client.go (9)
38-38
: Add Question import.
Adding the question
import helps integrate the new Question entity into the Ent client.
90-91
: Introduce QuestionClient field.
Declaring Question *QuestionClient
extends the top-level Ent client to support operations on the Question entity.
130-130
: Initialize QuestionClient in init().
Ensures the Question client is properly set up with the correct configuration.
246-246
: Add QuestionClient to transactional client.
Including Question: NewQuestionClient(cfg)
in the Tx creation ensures that Question operations can be performed in a transaction.
289-289
: Support QuestionClient in BeginTx.
Same rationale as above, allowing transactional operations on Questions.
326-326
: Enabling mutation hooks for Question.
Enables consistent application of hooks (logging, validation, etc.) across all entity operations, including Question.
339-339
: Enabling interceptors for Question.
Allows interceptors to be inherited for the Question entity, ensuring consistent query transformations or validations.
386-387
: Handle QuestionMutation in Mutate method.
Ensures the client dispatches Question mutations to the specialized Question.mutate
function.
637-651
: Add QueryQuestions for Account.
A new edge method to query the questions
relationship from an Account
, contributing to a more complete data model.
app/services/semdex/semdex.go (1)
46-46
: Switched from channels to a callback-based Ask.
This refactor replaces channels with a callback mechanism, offering a potentially more streamlined flow for yielding ask results. Confirm that upstream callers are updated accordingly.
internal/ent/er.html (2)
209-218
: Introduce “Question” entity.
Adding a new entity with fields like slug
, query
, and result
clarifies how questions are stored. The indexed_at
column can facilitate or track search indexing.
252-252
: Define relationship from Account to Question.
Enabling an account to reference multiple questions establishes a clear authoring relationship. This helps when linking user accounts to their questions.
app/resources/datagraph/content.go (2)
17-17
: Import blackfriday for Markdown support.
The new import is necessary for parsing Markdown content in newly introduced methods.
150-157
: Generate rich text from Markdown.
The new NewRichTextFromMarkdown
function provides a convenient way to convert Markdown into the existing Content
structure, preserving links, media, and references.
- key based on question, slugified - future work: vector lookup with tight threshold
1b4e04b
to
f69c1f8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (1)
internal/ent/question/where.go (1)
424-452
:⚠️ Potential issuePrevent partial matches on AccountID string operations.
Using string-based predicates (Contains, HasPrefix, HasSuffix) on xid.ID fields can lead to incorrect matches. These operations should be removed or replaced with exact matching.
-// AccountIDContains applies the Contains predicate on the "account_id" field. -func AccountIDContains(v xid.ID) predicate.Question { - vc := v.String() - return predicate.Question(sql.FieldContains(FieldAccountID, vc)) -} - -// AccountIDHasPrefix applies the HasPrefix predicate on the "account_id" field. -func AccountIDHasPrefix(v xid.ID) predicate.Question { - vc := v.String() - return predicate.Question(sql.FieldHasPrefix(FieldAccountID, vc)) -} - -// AccountIDHasSuffix applies the HasSuffix predicate on the "account_id" field. -func AccountIDHasSuffix(v xid.ID) predicate.Question { - vc := v.String() - return predicate.Question(sql.FieldHasSuffix(FieldAccountID, vc)) -}
🧹 Nitpick comments (6)
app/transports/http/bindings/datagraph.go (1)
62-65
: Add input validation for the query parameter.Consider validating the query parameter before passing it to
asker.Ask()
. Empty or malformed queries should be caught early to avoid unnecessary processing.+ if strings.TrimSpace(query) == "" { + return echo.NewHTTPError(http.StatusBadRequest, "Query parameter cannot be empty") + } + iter, err := d.asker.Ask(ctx, query)internal/ent/question_create.go (1)
268-269
: Fix grammatical error in comments.In the comments, "the was proposed for insertion" should be corrected to "that were proposed for insertion" for clarity.
Apply this diff to fix the grammatical errors:
// // Update the row with the new values -// // the was proposed for insertion. +// // that were proposed for insertion.Also applies to: 399-400, 674-675
app/services/semdex/asker/cached.go (1)
53-67
: Optimize chunking of markdown content incachedResult
The current implementation splits the markdown content into chunks using
strings.SplitAfter(string(md), " ")
, which splits after every space. This can result in very small chunks and may affect performance or user experience due to excessive processing and network overhead.Consider splitting the content into larger chunks, such as by sentences or paragraphs, to improve efficiency:
- chunks := strings.SplitAfter(string(md), " ") + chunks := strings.SplitAfter(string(md), "\n\n")Alternatively, implement a more sophisticated chunking mechanism that balances chunk size and readability.
app/services/semdex/asker/perplexity.go (1)
114-115
: Use structured logging instead offmt.Println
Logging with
fmt.Println
is not ideal for production code as it writes directly to standard output and lacks log levels and structured context. In line 114, replacefmt.Println
with your structured logger to provide better logging practices:- fmt.Println(string(event.Data)) + a.logger.Error("no citations in response", zap.String("response_data", string(event.Data)))app/services/semdex/asker/asker.go (1)
Line range hint
40-57
: Consider enhancing the answer prompt template.The template provides clear instructions but could be improved to handle edge cases:
- Add guidance for when no relevant sources are found
- Specify how to handle conflicting information from multiple sources
var AnswerPrompt = template.Must(template.New("").Parse(` You are an expert assistant. Answer the user's question accurately and concisely using the provided sources. Cite the sources in a separate list at the end of your answer. Ensure that the source URLs (in "sdr" format) are kept exactly as they appear, without modification or breaking them across lines. +If no relevant information is found in the provided sources, clearly state this limitation. +If sources contain conflicting information, acknowledge the discrepancy and explain your reasoning for the chosen answer. You MUST include references to the sources below in your answer in addition to other sources you may have. Sources:app/resources/datagraph/content_test.go (1)
129-159
: Add more test cases for edge cases.While the current test covers basic functionality, consider adding tests for:
- Empty content
- Malformed references
- Special characters in the content
- Very long content
t.Run("empty_content", func(t *testing.T) { ... }) t.Run("malformed_references", func(t *testing.T) { ... }) t.Run("special_characters", func(t *testing.T) { ... }) t.Run("very_long_content", func(t *testing.T) { ... })
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
go.mod
is excluded by!**/*.mod
go.sum
is excluded by!**/*.sum
,!**/*.sum
📒 Files selected for processing (38)
app/resources/datagraph/content.go
(2 hunks)app/resources/datagraph/content_test.go
(1 hunks)app/resources/question/question.go
(1 hunks)app/resources/question/repo.go
(1 hunks)app/resources/resources.go
(2 hunks)app/services/semdex/asker/asker.go
(1 hunks)app/services/semdex/asker/cached.go
(1 hunks)app/services/semdex/asker/default.go
(1 hunks)app/services/semdex/asker/perplexity.go
(4 hunks)app/services/semdex/semdex.go
(1 hunks)app/transports/http/bindings/datagraph.go
(2 hunks)internal/ent/account.go
(14 hunks)internal/ent/account/account.go
(4 hunks)internal/ent/account/where.go
(1 hunks)internal/ent/account_create.go
(3 hunks)internal/ent/account_query.go
(9 hunks)internal/ent/account_update.go
(7 hunks)internal/ent/client.go
(11 hunks)internal/ent/ent.go
(2 hunks)internal/ent/er.html
(2 hunks)internal/ent/hook/hook.go
(1 hunks)internal/ent/migrate/schema.go
(3 hunks)internal/ent/mutation.go
(15 hunks)internal/ent/predicate/predicate.go
(1 hunks)internal/ent/question.go
(1 hunks)internal/ent/question/question.go
(1 hunks)internal/ent/question/where.go
(1 hunks)internal/ent/question_create.go
(1 hunks)internal/ent/question_delete.go
(1 hunks)internal/ent/question_query.go
(1 hunks)internal/ent/question_update.go
(1 hunks)internal/ent/runtime.go
(2 hunks)internal/ent/schema/account.go
(1 hunks)internal/ent/schema/question.go
(1 hunks)internal/ent/tx.go
(2 hunks)internal/infrastructure/ai/ai.go
(2 hunks)internal/infrastructure/ai/mock.go
(1 hunks)internal/infrastructure/ai/openai.go
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (14)
- internal/ent/predicate/predicate.go
- internal/ent/schema/account.go
- app/services/semdex/semdex.go
- app/resources/resources.go
- internal/ent/hook/hook.go
- internal/ent/ent.go
- internal/ent/er.html
- app/resources/datagraph/content.go
- internal/ent/account.go
- app/resources/question/question.go
- internal/ent/schema/question.go
- internal/ent/question.go
- app/resources/question/repo.go
- internal/ent/question_delete.go
🔇 Additional comments (53)
internal/ent/tx.go (2)
55-56
: LGTM: Question client field added to Tx structThe Question client field is properly added to the Tx struct following the same pattern as other entities.
215-215
: LGTM: Question client initialization addedThe Question client is properly initialized in the init method using the standard NewQuestionClient constructor.
internal/ent/client.go (7)
38-38
: LGTM: Question schema import addedThe question schema package is properly imported.
90-91
: LGTM: Question client field added to Client structThe Question client field is properly added to the Client struct following the same pattern as other entities.
130-130
: LGTM: Question client initialization addedThe Question client is properly initialized in the init method using the standard NewQuestionClient constructor.
326-326
: LGTM: Question added to Use and Intercept methodsThe Question client is properly added to both Use and Intercept methods to support hooks and interceptors.
Also applies to: 339-339
386-387
: LGTM: Question added to Mutate methodThe Question mutation case is properly added to the Mutate method.
4254-4401
: LGTM: QuestionClient implementationThe QuestionClient implementation is complete and follows the standard ent patterns with all necessary CRUD operations and edge handling.
5052-5053
: LGTM: Question added to hooks and interceptors structsQuestion is properly added to both hooks and interceptors structs.
Also applies to: 5058-5059
internal/ent/question/question.go (1)
1-2
: Generated code by Ent frameworkThis file is auto-generated by the Ent framework. Direct modifications are not recommended as they may be overwritten. Ensure that any changes are made through the Ent schema definitions to maintain consistency.
internal/ent/question_update.go (1)
1-526
: The code changes in this file are auto-generated and comply with Ent framework conventions.The methods and structures for updating
Question
entities are correctly implemented. No issues are identified in the code.internal/ent/question_query.go (1)
1-630
: The query builder forQuestion
entities is correctly implemented.The code provides comprehensive querying capabilities, including predicates, ordering, eager-loading of related entities, and aggregation functions. No issues are found.
internal/ent/question_create.go (1)
1-880
: The rest of the code appears correct and follows Ent framework standards.All required fields and relationships are properly handled, and the upsert functionality is correctly implemented. No issues are detected.
internal/ent/account_update.go (4)
672-675
: Same potential nil pointer dereference inRemoveQuestions
methodThe
RemoveQuestions
method also accessesq[i].ID
without checking ifq[i]
is nil, which may cause a panic if a nil*Question
is passed. Please add a nil check similar to the one suggested forAddQuestions
.
2230-2233
: Add nil check inAddQuestions
method ofAccountUpdateOne
In the
AddQuestions
method ofAccountUpdateOne
, accessingq[i].ID
without checking for nil may lead to a panic if a nil*Question
is passed. Adding a nil check will prevent this issue.
2573-2576
: Potential nil pointer dereference inRemoveQuestions
method ofAccountUpdateOne
Similar to the previous methods, the
RemoveQuestions
method inAccountUpdateOne
may panic whenq[i]
is nil. Please add a nil check.
1370-1414
: Edge handling for questions insqlSave
methods is correctly implementedThe addition of edge handling for
questions
in thesqlSave
methods ofAccountUpdate
andAccountUpdateOne
appears to be correctly implemented and aligns with the existing patterns for other entities.Also applies to: 3301-3345
internal/ent/mutation.go (15)
34-34
: Import of 'question' package is appropriateThe import statement for the
question
package correctly includes the new 'Question' entity.
71-71
: Addition of 'TypeQuestion' constant is appropriateThe
TypeQuestion
constant is added to define the type name for the 'Question' entity, aligning with existing type definitions.
119-121
: Addition of 'questions' edge fields in 'AccountMutation'The fields
questions
,removedquestions
, andclearedquestions
are correctly added to theAccountMutation
struct to manage the 'questions' edge, following established patterns.
1159-1212
: Methods for managing 'questions' edge are correctly implementedThe methods
AddQuestionIDs
,RemoveQuestionIDs
,ClearQuestions
,QuestionsCleared
,QuestionsIDs
,RemovedQuestionsIDs
, andResetQuestions
are correctly added to manage the 'questions' edge inAccountMutation
, consistent with existing edge management methods.
2149-2149
: Initialization of 'edges' slice in 'AddedEdges' methodThe 'edges' slice is initialized with a capacity of 20 in the
AddedEdges
method, which is appropriate considering the number of potential edges.
2174-2176
: Include 'questions' edge in 'AddedEdges' methodThe 'questions' edge is correctly included in the
AddedEdges
method to ensure it's tracked when edges are added.
2263-2268
: Properly retrieve added 'questions' edge IDs in 'AddedIDs' methodThe implementation correctly retrieves the IDs of the added 'questions' edges in the
AddedIDs
method, ensuring they are processed appropriately.
2341-2341
: Initialization of 'edges' slice in 'RemovedEdges' methodThe 'edges' slice is initialized with a capacity of 20 in the
RemovedEdges
method, consistent with theAddedEdges
method.
2363-2365
: Include 'questions' edge in 'RemovedEdges' methodThe 'questions' edge is correctly included in the
RemovedEdges
method to track edges that have been removed.
2448-2453
: Properly retrieve removed 'questions' edge IDs in 'RemovedIDs' methodThe implementation correctly retrieves the IDs of the removed 'questions' edges in the
RemovedIDs
method.
2526-2526
: Initialization of 'edges' slice in 'ClearedEdges' methodThe 'edges' slice is initialized with a capacity of 20 in the
ClearedEdges
method, aligning with other edge methods.
2551-2553
: Include 'questions' edge in 'ClearedEdges' methodThe 'questions' edge is correctly included in the
ClearedEdges
method to track edges that have been cleared.
2610-2611
: Edge clearance check for 'questions' edge in 'EdgeCleared' methodThe method correctly checks if the 'questions' edge has been cleared.
2677-2679
: Resetting 'questions' edge in 'ResetEdge' methodThe
ResetQuestions
method is correctly called to reset changes to the 'questions' edge.
20374-21136
: Comprehensive implementation of 'QuestionMutation' struct and methodsThe
QuestionMutation
struct and all its associated methods are thoroughly implemented, enabling complete management of 'Question' entity mutations. The methods follow established patterns used in other entity mutations, ensuring consistency across the codebase.internal/ent/account_create.go (2)
291-304
: LGTM!The methods for adding questions follow the established pattern for edge management in the codebase.
761-776
: LGTM!The edge specification is correctly implemented in createSpec, following the same pattern as other edges.
internal/ent/account_query.go (5)
52-52
: LGTM!The field declaration follows the established pattern for edge query fields.
277-297
: LGTM!The query method correctly sets up the graph traversal for the questions edge.
848-857
: LGTM!The eager loading configuration is properly implemented.
1494-1523
: LGTM!The loading function correctly handles the loading of questions, including proper error handling and foreign key validation.
Line range hint
1058-1067
: LGTM!The loadedTypes array is correctly updated to include the questions edge.
internal/ent/migrate/schema.go (3)
694-704
: LGTM!The column definitions are comprehensive and include all necessary fields with appropriate types and constraints.
1015-1015
: LGTM!The table is correctly registered in the Tables slice and properly initialized.
Also applies to: 1069-1069
705-718
: Verify the OnDelete behavior for the account foreign key.The foreign key is set to
NoAction
which might prevent account deletion if there are associated questions. Consider whetherCascade
would be more appropriate to automatically clean up questions when an account is deleted.✅ Verification successful
The
NoAction
behavior for questions-accounts relationship is correctThe current behavior aligns with the codebase's pattern of preserving user-generated content. This is evidenced by similar
NoAction
treatment of posts-accounts relationships, suggesting a deliberate design choice to prevent content loss when accounts are deleted.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check if other similar edges use Cascade for cleanup rg --type go "OnDelete:\s+schema\.Cascade" internal/ent/migrate/Length of output: 2586
Script:
#!/bin/bash # Get context of foreign key definitions including table names rg --type go -B 2 "OnDelete:\s+schema\.(NoAction|Cascade)" internal/ent/migrate/schema.go # Also search for any comments about deletion behavior rg --type go "(?i)delete|cascade|foreign key" internal/ent/migrate/schema.goLength of output: 8603
internal/ent/account/where.go (1)
783-804
: LGTM!The predicate functions are correctly implemented, following the established pattern for edge predicates.
app/services/semdex/asker/default.go (1)
19-30
: RefactoredAsk
method improves control flow and error handlingThe updated
Ask
method transitions from a channel-based approach to a function-based iterator. This refactoring simplifies the control flow, enhances error handling, and improves the overall readability and maintainability of the code.internal/infrastructure/ai/openai.go (1)
Line range hint
46-81
: Proper handling of theyield
function in streaming responsesThe updated
PromptStream
method correctly utilizes theyield
function to send streaming responses and checks its return value to allow the caller to terminate the stream early. Error handling is appropriately managed by yielding errors when they occur, enhancing the robustness of the streaming logic.app/services/semdex/asker/perplexity.go (1)
108-115
: Verify if absence of citations should trigger an errorThe code returns an error when there are no citations in the response:
if len(cr.Citations) == 0 { // ... yield("", fmt.Errorf("no citations in response")) return }Ensure that the API is expected to always return citations. If the absence of citations is acceptable in certain cases, consider handling this scenario without returning an error to prevent unnecessary failures.
✅ Verification successful
Citations are required in Perplexity API responses
The code's behavior is correct. Citations appear to be a core part of the Perplexity API response structure, as evidenced by:
- Citations field is part of the CompletionResponse struct
- Response processing includes citation marker handling
- No configuration options exist to make citations optional
🏁 Scripts executed
The following scripts were executed for the analysis:
Error: No shell scripts found
Script:
#!/bin/bash # Search for Perplexity-related files fd perplexity # Search for citation-related code rg -i "citations?" -A 5 -B 5 # Look for documentation about Perplexity integration fd "README|docs" --extension md | xargs rg -i "perplexity|citation" # Search for any configuration related to citations rg -i "citation.*required" -A 5 -B 5Length of output: 70867
Script:
#!/bin/bash # Search for perplexity test files fd perplexity.*test # Search for configuration files fd "config|settings" --type f # Search for citation-related code in test files rg -i "citation" --type test # Look for perplexity configuration rg -i "perplexity.*config" -A 5 -B 5Length of output: 3249
internal/infrastructure/ai/ai.go (1)
17-17
: Ensure all implementations ofPrompter
interface are updatedThe
PromptStream
method signature in thePrompter
interface has been changed. Verify that all implementations of this interface, as well as any consumers, are updated accordingly to comply with the new method signature and to prevent runtime errors.app/services/semdex/asker/asker.go (1)
21-38
: LGTM! Clean separation of concerns.The refactoring improves modularity by:
- Separating asker creation logic into a helper function
- Adding caching capability through composition
internal/ent/runtime.go (1)
801-831
: LGTM! Standard entity initialization.The question entity initialization follows the established pattern with proper setup of:
- Field descriptors
- Default values
- ID validation
internal/ent/account/account.go (4)
56-57
: LGTM! Edge constant follows the established pattern.The new
EdgeQuestions
constant follows the consistent naming pattern and is properly documented.
138-144
: LGTM! Table constants are well-defined.The table constants for the questions edge are properly defined with clear documentation of their purpose and relationships.
432-444
: LGTM! Ordering functions are correctly implemented.The
ByQuestionsCount
andByQuestions
functions follow the established pattern for edge ordering, properly handling both count-based and term-based ordering scenarios.
655-661
: LGTM! Graph step function is properly implemented.The
newQuestionsStep
function correctly sets up the One-to-Many relationship between accounts and questions, following the consistent pattern used throughout the codebase.
for chunk, err := range iter { | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if flusher != nil { | ||
flusher.Flush() | ||
} | ||
if _, err := w.Write([]byte(chunk)); err != nil { | ||
return err | ||
} | ||
|
||
case err := <-errSignal: | ||
if err != nil { | ||
return err | ||
} | ||
if flusher != nil { | ||
flusher.Flush() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance context cancellation handling.
The iterator loop should respect context cancellation to handle client disconnections gracefully. Consider adding context checks within the loop.
for chunk, err := range iter {
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ default:
if err != nil {
return err
}
if _, err := w.Write([]byte(chunk)); err != nil {
return err
}
if flusher != nil {
flusher.Flush()
}
+ }
}
Committable suggestion skipped: line range outside the PR's diff.
iter, err := a.asker.Ask(ctx, q) | ||
if err != nil { | ||
return nil, fault.Wrap(err, fctx.With(ctx)) | ||
} | ||
|
||
return func(yield func(string, error) bool) { | ||
acc := []string{} | ||
|
||
defer func() { | ||
err := a.cacheResult(ctx, accountID, q, acc) | ||
if err != nil { | ||
a.logger.Error("failed to cache result", zap.Error(err)) | ||
} | ||
}() | ||
|
||
for chunk, err := range iter { | ||
if err != nil { | ||
yield("", err) | ||
return | ||
} | ||
|
||
acc = append(acc, chunk) | ||
if !yield(chunk, nil) { | ||
return | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct the usage of the iter
function in livePrompt
method
In the livePrompt
method, the iter
variable is a function returned by a.asker.Ask(ctx, q)
with the signature func(yield func(string, error) bool)
. However, it is incorrectly used as an iterator in a for
loop:
for chunk, err := range iter {
if err != nil {
yield("", err)
return
}
acc = append(acc, chunk)
if !yield(chunk, nil) {
return
}
}
This usage is invalid because iter
is not an iterator. Instead, you should call iter
and pass a yield
function to handle the chunks and errors.
Apply this diff to fix the issue:
func (a *cachedAsker) livePrompt(ctx context.Context, q string) (func(yield func(string, error) bool), error) {
accountID, err := session.GetAccountID(ctx)
if err != nil {
return nil, fault.Wrap(err, fctx.With(ctx))
}
iter, err := a.asker.Ask(ctx, q)
if err != nil {
return nil, fault.Wrap(err, fctx.With(ctx))
}
return func(yield func(string, error) bool) {
acc := []string{}
defer func() {
err := a.cacheResult(ctx, accountID, q, acc)
if err != nil {
a.logger.Error("failed to cache result", zap.Error(err))
}
}()
- for chunk, err := range iter {
- if err != nil {
- yield("", err)
- return
- }
-
- acc = append(acc, chunk)
- if !yield(chunk, nil) {
- return
- }
- }
+ err := iter(func(chunk string, err error) bool {
+ if err != nil {
+ yield("", err)
+ return false
+ }
+ acc = append(acc, chunk)
+ return yield(chunk, nil)
+ })
+ if err != nil {
+ yield("", err)
+ return
+ }
}, nil
}