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
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# frozen_string_literal: true

module Mutations
module Velorum
module Ai
class GenerateFlow < BaseMutation
description 'Start a Velorum flow generation job.'
description 'Start an AI flow generation job.'

field :execution_identifier,
type: GraphQL::Types::String,
Expand All @@ -17,18 +17,18 @@ class GenerateFlow < BaseMutation
argument :model_identifier,
type: GraphQL::Types::String,
required: true,
description: 'Selected Velorum model identifier'
description: 'Selected AI model identifier'
argument :project_id,
type: Types::GlobalIdType[::NamespaceProject],
required: true,
description: 'Project to generate a flow for'
argument :prompt,
type: GraphQL::Types::String,
required: true,
description: 'Prompt to send to Velorum'
description: 'Prompt to send to AI'

def resolve(project_id:, prompt:, model_identifier:, flow_id: nil)
return error_response(:invalid_setting, 'Velorum is disabled') unless velorum_enabled?
return error_response(:invalid_setting, 'AI is disabled') unless ai_enabled?

project = SagittariusSchema.object_from_id(project_id)
return error_response(:project_not_found, 'Invalid project id') if project.nil?
Expand All @@ -50,7 +50,7 @@ def resolve(project_id:, prompt:, model_identifier:, flow_id: nil)

private

def velorum_enabled?
def ai_enabled?
Sagittarius::Configuration.config[:velorum][:enabled]
end

Expand Down
4 changes: 2 additions & 2 deletions app/graphql/subscription_triggers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ def self.execution_result(execution_result)
)
end

def self.velorum_generate_flow(execution_identifier, flow)
def self.ai_generate_flow(execution_identifier, flow)
SagittariusSchema.subscriptions.trigger(
:velorum_generate_flow,
:ai_generate_flow,
{ execution_identifier: execution_identifier },
flow,
context: { visibility_profile: :execution }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# frozen_string_literal: true

module Subscriptions
module Velorum
module Ai
class GenerateFlow < BaseSubscription
description 'Generate a flow through Velorum and close the subscription with the generated flow'
description 'Generate a flow through AI and close the subscription with the generated flow'

argument :execution_identifier,
type: GraphQL::Types::String,
required: true,
description: 'Velorum generation request identifier returned by the mutation'
description: 'AI generation request identifier returned by the mutation'

field :flow,
type: GraphQL::Types::JSON,
type: Types::Ai::GenerationFlowType,
null: true,
description: 'Generated flow returned by Velorum'
description: 'Generated flow returned by AI'

def subscribe(**)
:no_response
Expand Down
19 changes: 19 additions & 0 deletions app/graphql/types/ai/generation_flow_setting_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module Types
module Ai
class GenerationFlowSettingType < Types::BaseObject
description 'Represents a flow setting generated by AI.'

field :cast, String, null: true, description: 'The generated cast applied to the flow setting.'
field :flow_setting_id, String, null: true, description: 'The generated flow setting identifier.'
field :id, Types::GlobalIdType[::FlowSetting], null: false,
description: 'Generated global ID for this setting.'
field :value, GraphQL::Types::JSON, null: true, description: 'The generated value of the flow setting.'

def id
Sagittarius::Utils.generated_global_id(object[:id], ::FlowSetting)
end
end
end
end
25 changes: 25 additions & 0 deletions app/graphql/types/ai/generation_flow_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

module Types
module Ai
class GenerationFlowType < Types::BaseObject
description 'Represents a flow generated by AI.'

field :name, String, null: true, description: 'Generated flow name.'
field :nodes, [Types::Ai::GenerationNodeFunctionType],
null: false,
description: 'Generated node functions of the flow.'
field :settings, [Types::Ai::GenerationFlowSettingType],
null: false,
description: 'Generated flow settings.'
field :starting_node_id, Types::GlobalIdType[::NodeFunction],
null: true,
description: 'Generated starting node ID.'
field :type, String, null: true, description: 'Generated flow type identifier.'

def starting_node_id
Sagittarius::Utils.generated_global_id(object[:starting_node_id], ::NodeFunction)
end
end
end
end
23 changes: 23 additions & 0 deletions app/graphql/types/ai/generation_input_type_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

module Types
module Ai
class GenerationInputTypeType < Types::BaseObject
description 'Represents an input type reference generated by AI.'

field :input_index, GraphQL::Types::Int,
null: true,
description: 'The generated referenced input index.'
field :node_id, Types::GlobalIdType[::NodeFunction],
null: true,
description: 'The generated referenced node ID.'
field :parameter_index, GraphQL::Types::Int,
null: true,
description: 'The generated referenced parameter index.'

def node_id
Sagittarius::Utils.generated_global_id(object[:node_id], ::NodeFunction)
end
end
end
end
28 changes: 28 additions & 0 deletions app/graphql/types/ai/generation_node_function_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

module Types
module Ai
class GenerationNodeFunctionType < Types::BaseObject
description 'Represents a node function generated by AI.'

field :function_definition, Types::FunctionDefinitionType,
null: true,
description: 'Resolved function definition for the generated node.'
field :id, Types::GlobalIdType[::NodeFunction], null: false, description: 'Generated global ID for this node.'
field :next_node_id, Types::GlobalIdType[::NodeFunction],
null: true,
description: 'Generated next node ID.'
field :parameters, [Types::Ai::GenerationNodeParameterType],
null: false,
description: 'Generated node parameters.'

def id
Sagittarius::Utils.generated_global_id(object[:id], ::NodeFunction)
end

def next_node_id
Sagittarius::Utils.generated_global_id(object[:next_node_id], ::NodeFunction)
end
end
end
end
22 changes: 22 additions & 0 deletions app/graphql/types/ai/generation_node_parameter_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module Types
module Ai
class GenerationNodeParameterType < Types::BaseObject
description 'Represents a node parameter generated by AI.'

field :cast, String, null: true, description: 'The generated cast applied to the parameter.'
field :id, Types::GlobalIdType[::NodeParameter],
null: false,
description: 'Generated global ID for this parameter.'
field :parameter_definition, Types::ParameterDefinitionType,
null: true,
description: 'Resolved parameter definition for the generated parameter.'
field :value, Types::Ai::GenerationNodeValueType, null: true, description: 'The generated parameter value.'

def id
Sagittarius::Utils.generated_global_id(object[:id], ::NodeParameter)
end
end
end
end
26 changes: 26 additions & 0 deletions app/graphql/types/ai/generation_node_value_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

module Types
module Ai
class GenerationNodeValueType < Types::BaseUnion
description 'Represents a node value generated by AI.'

possible_types Types::LiteralValueType,
Types::Ai::GenerationReferenceValueType,
Types::Ai::GenerationSubFlowValueType

def self.resolve_type(object, _context)
generated_value_type = object[:generated_value_type] || object['generated_value_type'] if object.is_a?(Hash)

case generated_value_type&.to_sym
when :reference_value
Types::Ai::GenerationReferenceValueType
when :sub_flow_value
Types::Ai::GenerationSubFlowValueType
else
Types::LiteralValueType
end
end
end
end
end
16 changes: 16 additions & 0 deletions app/graphql/types/ai/generation_reference_path_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

module Types
module Ai
class GenerationReferencePathType < Types::BaseObject
description 'Represents a reference path generated by AI.'

field :array_index, GraphQL::Types::Int,
null: true,
description: 'The generated reference array index.'
field :path, String,
null: true,
description: 'The generated reference path.'
end
end
end
41 changes: 41 additions & 0 deletions app/graphql/types/ai/generation_reference_value_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

module Types
module Ai
class GenerationReferenceValueType < Types::BaseObject
description 'Represents a reference value generated by AI.'

field :flow_input, Boolean,
null: true,
description: 'Whether this reference targets the flow input, matching the gRPC field.'
# rubocop:disable GraphQL/ExtractType -- keep both gRPC and existing frontend names available.
field :input_index, GraphQL::Types::Int,
null: true,
description: 'The generated referenced input index.'
field :input_type, Types::Ai::GenerationInputTypeType,
null: true,
description: 'The generated input type reference, matching the gRPC field.'
field :node_function_id, Types::GlobalIdType[::NodeFunction],
null: true,
description: 'The generated referenced node function ID.'
field :node_id, Types::GlobalIdType[::NodeFunction],
null: true,
description: 'The generated referenced node ID, matching the gRPC field.'
# rubocop:enable GraphQL/ExtractType
field :parameter_index, GraphQL::Types::Int,
null: true,
description: 'The generated referenced parameter index.'
field :reference_path, [Types::Ai::GenerationReferencePathType],
null: false,
description: 'The generated reference paths.'

def node_function_id
Sagittarius::Utils.generated_global_id(object[:node_function_id], ::NodeFunction)
end

def node_id
Sagittarius::Utils.generated_global_id(object[:node_id], ::NodeFunction)
end
end
end
end
22 changes: 22 additions & 0 deletions app/graphql/types/ai/generation_sub_flow_setting_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module Types
module Ai
class GenerationSubFlowSettingType < Types::BaseObject
description 'Represents a sub-flow setting generated by AI.'

field :default_value, GraphQL::Types::JSON,
null: true,
description: 'The generated default value of the sub-flow setting.'
field :hidden, Boolean,
null: true,
description: 'Whether the generated sub-flow setting is hidden.'
field :identifier, String,
null: true,
description: 'The generated sub-flow setting identifier.'
field :optional, Boolean,
null: true,
description: 'Whether the generated sub-flow setting is optional.'
end
end
end
26 changes: 26 additions & 0 deletions app/graphql/types/ai/generation_sub_flow_value_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

module Types
module Ai
class GenerationSubFlowValueType < Types::BaseObject
description 'Represents a sub-flow value generated by AI.'

field :function_identifier, String,
null: true,
description: 'The generated sub-flow function identifier.'
field :settings, [Types::Ai::GenerationSubFlowSettingType],
null: false,
description: 'The generated sub-flow settings.'
field :signature, String,
null: true,
description: 'The generated sub-flow signature.'
field :starting_node_id, Types::GlobalIdType[::NodeFunction],
null: true,
description: 'The generated sub-flow starting node ID.'

def starting_node_id
Sagittarius::Utils.generated_global_id(object[:starting_node_id], ::NodeFunction)
end
end
end
end
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# frozen_string_literal: true

module Types
class VelorumModelType < Types::BaseObject
description 'Represents a model available through Velorum'
class AiModelType < Types::BaseObject
description 'Represents a model available through AI'

field :identifier, String, null: false, description: 'Unique model identifier'
field :name, String, null: false, description: 'Human-readable model name'
field :token_cost, Float, null: false, description: 'Token cost for using this model'
field :types, [Types::VelorumModelTypeEnum],
field :types, [Types::AiModelTypeEnum],
null: false,
description: 'Capabilities supported by this model',
method: :type
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# frozen_string_literal: true

module Types
class VelorumModelTypeEnum < Types::BaseEnum
description 'Supported Velorum model capabilities'
class AiModelTypeEnum < Types::BaseEnum
description 'Supported AI model capabilities'

value :UNKNOWN, 'Unknown model capability', value: :UNKNOWN
value :EXPLAIN, 'Model can explain flows', value: :EXPLAIN
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# frozen_string_literal: true

module Types
class VelorumType < Types::BaseObject
description 'Represents Velorum integration information'
class AiType < Types::BaseObject
description 'Represents AI integration information'

authorize :read_velorum_config
declarative_policy_subject { :global }

field :enabled, Boolean, null: false, description: 'Whether Velorum is enabled'
field :models, [Types::VelorumModelType], null: false, description: 'Find models available through Velorum'
field :enabled, Boolean, null: false, description: 'Whether AI is enabled'
field :models, [Types::AiModelType], null: false, description: 'Find models available through AI'

def enabled
config[:enabled]
Expand Down
Loading