...
This commit is contained in:
30
examples/ai/flow_test1.vsh
Executable file
30
examples/ai/flow_test1.vsh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
import incubaid.herolib.ai.client
|
||||
|
||||
mut cl := client.new()!
|
||||
|
||||
// response := cl.llms.llm_local.chat_completion(
|
||||
// message: 'Explain quantum computing in simple terms'
|
||||
// temperature: 0.5
|
||||
// max_completion_tokens: 1024
|
||||
// )!
|
||||
|
||||
response := cl.llms.llm_maverick.chat_completion(
|
||||
message: 'Explain quantum computing in simple terms'
|
||||
temperature: 0.5
|
||||
max_completion_tokens: 1024
|
||||
)!
|
||||
|
||||
println(response)
|
||||
|
||||
// response := cl.llms.llm_embed_local.embed(input: [
|
||||
// 'The food was delicious and the waiter..',
|
||||
// ])!
|
||||
|
||||
// response2 := cl.llms.llm_embed.embed(input: [
|
||||
// 'The food was delicious and the waiter..',
|
||||
// ])!
|
||||
|
||||
|
||||
println(response2)
|
||||
@@ -5,7 +5,7 @@ import incubaid.herolib.core.flows
|
||||
|
||||
type CoordinatorProxy = flows.Coordinator
|
||||
|
||||
pub fn (mut c CoordinatorProxy) start(prompt string) ! {
|
||||
pub fn start(mut c flows.Coordinator, prompt string) ! {
|
||||
// init the heromodels, define well chosen name, needed to call later
|
||||
mut m := heromodels.new(redis: c.redis, name: 'coordinator_${c.name}')!
|
||||
|
||||
|
||||
@@ -10,14 +10,17 @@ import incubaid.herolib.core.logger
|
||||
import incubaid.herolib.ai.client as aiclient
|
||||
import incubaid.herolib.core.redisclient
|
||||
import incubaid.herolib.data.paramsparser
|
||||
import incubaid.herolib.core.texttools
|
||||
|
||||
@[heap]
|
||||
pub struct Coordinator {
|
||||
pub mut:
|
||||
name string
|
||||
steps map[string]Step
|
||||
logger logger.Logger
|
||||
ai aiclient.AIClient
|
||||
redis ?&redisclient.Redis
|
||||
name string
|
||||
current_step string // links to steps dict
|
||||
steps map[string]&Step
|
||||
logger logger.Logger
|
||||
ai aiclient.AIClient
|
||||
redis ?&redisclient.Redis
|
||||
}
|
||||
|
||||
pub fn new() !Coordinator {
|
||||
@@ -41,8 +44,8 @@ pub mut:
|
||||
}
|
||||
|
||||
// add step to it
|
||||
pub fn (mut c Coordinator) step_new(args StepNewArgs) !Step {
|
||||
return Step{
|
||||
pub fn (mut c Coordinator) step_new(args StepNewArgs) !&Step {
|
||||
mut s := Step{
|
||||
coordinator: &c
|
||||
name: args.name
|
||||
description: args.description
|
||||
@@ -52,4 +55,14 @@ pub fn (mut c Coordinator) step_new(args StepNewArgs) !Step {
|
||||
error: args.error
|
||||
params: args.params
|
||||
}
|
||||
s.name = texttools.name_fix(s.name)
|
||||
c.steps[s.name] = &s
|
||||
c.current_step = s.name
|
||||
return &s
|
||||
}
|
||||
|
||||
pub fn (mut c Coordinator) step_current() !&Step {
|
||||
return c.steps[c.current_step] or {
|
||||
return error('Current step "${c.current_step}" not found in coordinator "${c.name}"')
|
||||
}
|
||||
}
|
||||
|
||||
95
lib/core/flows/run.v
Normal file
95
lib/core/flows/run.v
Normal file
@@ -0,0 +1,95 @@
|
||||
module flows
|
||||
|
||||
import time as ostime
|
||||
|
||||
// Run the entire flow starting from current_step
|
||||
pub fn (mut c Coordinator) run() ! {
|
||||
mut s := c.step_current()!
|
||||
c.run_step(mut s)!
|
||||
}
|
||||
|
||||
// Run a single step, including error and next steps
|
||||
pub fn (mut c Coordinator) run_step(mut step Step) ! {
|
||||
// Initialize step
|
||||
step.status = .running
|
||||
step.started_at = ostime.now().unix_milli()
|
||||
step.store_redis()!
|
||||
|
||||
// Log step start
|
||||
step.log(
|
||||
level: .info
|
||||
message: 'Step "${step.name}" started'
|
||||
)!
|
||||
|
||||
// Execute main step function
|
||||
step.main_step(mut step) or {
|
||||
// Handle error
|
||||
step.status = .error
|
||||
step.error_msg = err.msg()
|
||||
step.finished_at = ostime.now().unix_milli()
|
||||
step.store_redis()!
|
||||
|
||||
step.log(
|
||||
level: .error
|
||||
message: 'Step "${step.name}" failed: ${err.msg()}'
|
||||
)!
|
||||
|
||||
// Run error steps if any
|
||||
if step.error_steps.len > 0 {
|
||||
for mut error_step in step.error_steps {
|
||||
c.run_step(mut error_step)!
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Mark as success
|
||||
step.status = .success
|
||||
step.finished_at = ostime.now().unix_milli()
|
||||
step.store_redis()!
|
||||
|
||||
step.log(
|
||||
level: .info
|
||||
message: 'Step "${step.name}" completed successfully'
|
||||
)!
|
||||
|
||||
// Run next steps if any
|
||||
if step.next_steps.len > 0 {
|
||||
for mut next_step in step.next_steps {
|
||||
c.run_step(mut next_step)!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get step state from redis
|
||||
pub fn (c Coordinator) get_step_state(step_name string) !map[string]string {
|
||||
if redis := c.redis {
|
||||
return redis.hgetall('flow:${c.name}:${step_name}')!
|
||||
}
|
||||
return error('Redis not configured')
|
||||
}
|
||||
|
||||
// Get all steps state from redis (for UI dashboard)
|
||||
pub fn (c Coordinator) get_all_steps_state() ![]map[string]string {
|
||||
mut states := []map[string]string{}
|
||||
if redis := c.redis {
|
||||
pattern := 'flow:${c.name}:*'
|
||||
keys := redis.keys(pattern)!
|
||||
for key in keys {
|
||||
state := redis.hgetall(key)!
|
||||
states << state
|
||||
}
|
||||
}
|
||||
return states
|
||||
}
|
||||
|
||||
pub fn (c Coordinator) clear_redis() ! {
|
||||
if redis := c.redis {
|
||||
pattern := 'flow:${c.name}:*'
|
||||
keys := redis.keys(pattern)!
|
||||
for key in keys {
|
||||
redis.del(key)!
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,20 @@ module flows
|
||||
import incubaid.herolib.data.paramsparser
|
||||
import incubaid.herolib.core.logger
|
||||
|
||||
pub enum StepStatus {
|
||||
pending
|
||||
running
|
||||
success
|
||||
error
|
||||
skipped
|
||||
}
|
||||
|
||||
pub struct Step {
|
||||
pub mut:
|
||||
status StepStatus = .pending
|
||||
started_at i64 // Unix timestamp
|
||||
finished_at i64
|
||||
error_msg string
|
||||
name string
|
||||
description string
|
||||
main_step fn (mut s Step) ! @[required]
|
||||
|
||||
@@ -188,15 +188,9 @@ fn test_prd_list() ! {
|
||||
mut mydb := db.new_test()!
|
||||
// Clear the test database to ensure clean state
|
||||
mydb.redis.flushdb()!
|
||||
|
||||
mut db_prd := DBPrd{
|
||||
db: &mydb
|
||||
}
|
||||
// Clear any existing PRDs before running the test
|
||||
existing_prds := db_prd.list()!
|
||||
for prd_id in existing_prds {
|
||||
db_prd.delete[ProductRequirementsDoc](u32(prd_id))!
|
||||
}
|
||||
|
||||
// Create multiple PRDs
|
||||
for i in 0 .. 3 {
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
module core
|
||||
|
||||
// Comment represents a generic commenting functionality that can be associated with any other model
|
||||
// It supports threaded conversations through parent_comment_id
|
||||
@[heap]
|
||||
pub struct Comment {
|
||||
pub mut:
|
||||
id u32 // Unique comment ID
|
||||
user_id u32 // ID of the user who posted the comment (indexed)
|
||||
content string // The text content of the comment
|
||||
parent_comment_id ?u32 // Optional parent comment ID for threaded comments
|
||||
created_at u64 // Creation timestamp
|
||||
updated_at u64 // Last update timestamp
|
||||
}
|
||||
|
||||
// new creates a new Comment with default values
|
||||
pub fn Comment.new() Comment {
|
||||
return Comment{
|
||||
id: 0
|
||||
user_id: 0
|
||||
content: ''
|
||||
parent_comment_id: none
|
||||
created_at: 0
|
||||
updated_at: 0
|
||||
}
|
||||
}
|
||||
|
||||
// user_id sets the user ID for the comment (builder pattern)
|
||||
pub fn (mut c Comment) user_id(id u32) Comment {
|
||||
c.user_id = id
|
||||
return c
|
||||
}
|
||||
|
||||
// content sets the content for the comment (builder pattern)
|
||||
pub fn (mut c Comment) content(text string) Comment {
|
||||
c.content = text
|
||||
return c
|
||||
}
|
||||
|
||||
// parent_comment_id sets the parent comment ID for threaded comments (builder pattern)
|
||||
pub fn (mut c Comment) parent_comment_id(parent_id ?u32) Comment {
|
||||
c.parent_comment_id = parent_id
|
||||
return c
|
||||
}
|
||||
|
||||
// is_top_level returns true if this is a top-level comment (no parent)
|
||||
pub fn (c Comment) is_top_level() bool {
|
||||
return c.parent_comment_id == none
|
||||
}
|
||||
|
||||
// is_reply returns true if this is a reply to another comment
|
||||
pub fn (c Comment) is_reply() bool {
|
||||
return c.parent_comment_id != none
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
module flow
|
||||
module flow
|
||||
|
||||
// Flow represents a signing flow
|
||||
@[heap]
|
||||
|
||||
Reference in New Issue
Block a user