chat_sdk 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/chat_sdk/ai/converter.rb +56 -0
- data/lib/chat_sdk/ai/stream_handler.rb +13 -0
- data/lib/chat_sdk/ai/tool_builder.rb +154 -0
- data/lib/chat_sdk/ai/tool_executor.rb +93 -0
- data/lib/chat_sdk/ai.rb +15 -0
- data/lib/chat_sdk/cards/node.rb +0 -4
- data/lib/chat_sdk/dispatcher.rb +8 -25
- data/lib/chat_sdk/events/action.rb +1 -0
- data/lib/chat_sdk/events/reaction.rb +1 -0
- data/lib/chat_sdk/events/slash_command.rb +1 -0
- data/lib/chat_sdk/thread.rb +4 -0
- data/lib/chat_sdk/version.rb +1 -1
- data/lib/chat_sdk.rb +1 -1
- metadata +6 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a8db1850adc2b313ad351d222eed5ed588f6c46b122bcf9f6f8f3eba445c19d5
|
|
4
|
+
data.tar.gz: 5fd507fa0cb224b1e204f5eeaedee74379769f4f9c5a8055af4549ecb1bbc97f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8af8ee31c13cbc5acccef41282ad5717ad2b2ff149fed4bcec95bfdb9fc6c422560d4d55c965e992cc1df1194232813b64f62653cc4c158ff51b4226768f871c
|
|
7
|
+
data.tar.gz: 0d1132b3d7f19f466aeb29c0d5827af6abc7702a917c90b1d679675239d24fda092b7d273830f881dd0b2e9693a1a975b6f3e6f1ff22f4c4652dbb876489915e
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChatSDK
|
|
4
|
+
module AI
|
|
5
|
+
class Converter
|
|
6
|
+
ROLE_USER = "user"
|
|
7
|
+
ROLE_ASSISTANT = "assistant"
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
def to_ai_messages(messages, include_names: false, &transform)
|
|
11
|
+
messages
|
|
12
|
+
.sort_by { |m| m.timestamp || m.id }
|
|
13
|
+
.reject { |m| m.text.nil? || m.text.strip.empty? }
|
|
14
|
+
.filter_map { |m| convert_message(m, include_names: include_names, &transform) }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def convert_message(message, include_names: false)
|
|
20
|
+
role = message.author&.bot? ? ROLE_ASSISTANT : ROLE_USER
|
|
21
|
+
|
|
22
|
+
content = message.text
|
|
23
|
+
if include_names && role == ROLE_USER && message.author
|
|
24
|
+
content = "[#{message.author.name}]: #{content}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
result = {role: role, content: content}
|
|
28
|
+
|
|
29
|
+
if message.attachments&.any?
|
|
30
|
+
parts = [{type: "text", text: content}]
|
|
31
|
+
message.attachments.each do |att|
|
|
32
|
+
parts << attachment_to_part(att)
|
|
33
|
+
end
|
|
34
|
+
result[:content] = parts
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
result = yield(result, message) if block_given?
|
|
38
|
+
result
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def attachment_to_part(attachment)
|
|
42
|
+
if attachment.is_a?(Hash)
|
|
43
|
+
mime = attachment[:mime_type] || attachment[:content_type] || "application/octet-stream"
|
|
44
|
+
if mime.start_with?("image/")
|
|
45
|
+
{type: "image", url: attachment[:url], media_type: mime}
|
|
46
|
+
else
|
|
47
|
+
{type: "file", url: attachment[:url], filename: attachment[:filename], media_type: mime}
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
{type: "text", text: attachment.to_s}
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChatSDK
|
|
4
|
+
module AI
|
|
5
|
+
class StreamHandler
|
|
6
|
+
def self.stream_to_thread(thread, enumerable, placeholder: "Thinking...")
|
|
7
|
+
thread.post_stream(placeholder: placeholder) do |stream|
|
|
8
|
+
enumerable.each { |chunk| stream << chunk.to_s }
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChatSDK
|
|
4
|
+
module AI
|
|
5
|
+
class ToolBuilder
|
|
6
|
+
PRESETS = {
|
|
7
|
+
reader: %i[fetch_messages fetch_thread],
|
|
8
|
+
messenger: %i[fetch_messages fetch_thread post_message send_direct_message add_reaction start_typing],
|
|
9
|
+
moderator: %i[fetch_messages fetch_thread post_message send_direct_message add_reaction
|
|
10
|
+
edit_message delete_message remove_reaction start_typing]
|
|
11
|
+
}.freeze
|
|
12
|
+
|
|
13
|
+
TOOL_DEFINITIONS = {
|
|
14
|
+
fetch_messages: {
|
|
15
|
+
description: "Fetch recent messages from a channel or thread",
|
|
16
|
+
parameters: {
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
adapter_name: {type: "string", description: "Adapter name (e.g., 'slack', 'teams')"},
|
|
20
|
+
channel_id: {type: "string", description: "Channel ID"},
|
|
21
|
+
thread_id: {type: "string", description: "Thread ID (optional)"},
|
|
22
|
+
limit: {type: "integer", description: "Max messages to fetch", default: 20}
|
|
23
|
+
},
|
|
24
|
+
required: %w[adapter_name channel_id]
|
|
25
|
+
},
|
|
26
|
+
read_only: true
|
|
27
|
+
},
|
|
28
|
+
fetch_thread: {
|
|
29
|
+
description: "Fetch all messages in a specific thread",
|
|
30
|
+
parameters: {
|
|
31
|
+
type: "object",
|
|
32
|
+
properties: {
|
|
33
|
+
adapter_name: {type: "string", description: "Adapter name"},
|
|
34
|
+
channel_id: {type: "string", description: "Channel ID"},
|
|
35
|
+
thread_id: {type: "string", description: "Thread ID"}
|
|
36
|
+
},
|
|
37
|
+
required: %w[adapter_name channel_id thread_id]
|
|
38
|
+
},
|
|
39
|
+
read_only: true
|
|
40
|
+
},
|
|
41
|
+
post_message: {
|
|
42
|
+
description: "Post a message to a channel or thread",
|
|
43
|
+
parameters: {
|
|
44
|
+
type: "object",
|
|
45
|
+
properties: {
|
|
46
|
+
adapter_name: {type: "string", description: "Adapter name"},
|
|
47
|
+
channel_id: {type: "string", description: "Channel ID"},
|
|
48
|
+
thread_id: {type: "string", description: "Thread ID (optional, for replies)"},
|
|
49
|
+
text: {type: "string", description: "Message text (markdown)"}
|
|
50
|
+
},
|
|
51
|
+
required: %w[adapter_name channel_id text]
|
|
52
|
+
},
|
|
53
|
+
read_only: false
|
|
54
|
+
},
|
|
55
|
+
send_direct_message: {
|
|
56
|
+
description: "Send a direct message to a user",
|
|
57
|
+
parameters: {
|
|
58
|
+
type: "object",
|
|
59
|
+
properties: {
|
|
60
|
+
adapter_name: {type: "string", description: "Adapter name"},
|
|
61
|
+
user_id: {type: "string", description: "User ID"},
|
|
62
|
+
text: {type: "string", description: "Message text"}
|
|
63
|
+
},
|
|
64
|
+
required: %w[adapter_name user_id text]
|
|
65
|
+
},
|
|
66
|
+
read_only: false
|
|
67
|
+
},
|
|
68
|
+
edit_message: {
|
|
69
|
+
description: "Edit an existing message",
|
|
70
|
+
parameters: {
|
|
71
|
+
type: "object",
|
|
72
|
+
properties: {
|
|
73
|
+
adapter_name: {type: "string", description: "Adapter name"},
|
|
74
|
+
channel_id: {type: "string", description: "Channel ID"},
|
|
75
|
+
message_id: {type: "string", description: "Message ID to edit"},
|
|
76
|
+
text: {type: "string", description: "New message text"}
|
|
77
|
+
},
|
|
78
|
+
required: %w[adapter_name channel_id message_id text]
|
|
79
|
+
},
|
|
80
|
+
read_only: false
|
|
81
|
+
},
|
|
82
|
+
delete_message: {
|
|
83
|
+
description: "Delete a message",
|
|
84
|
+
parameters: {
|
|
85
|
+
type: "object",
|
|
86
|
+
properties: {
|
|
87
|
+
adapter_name: {type: "string", description: "Adapter name"},
|
|
88
|
+
channel_id: {type: "string", description: "Channel ID"},
|
|
89
|
+
message_id: {type: "string", description: "Message ID to delete"}
|
|
90
|
+
},
|
|
91
|
+
required: %w[adapter_name channel_id message_id]
|
|
92
|
+
},
|
|
93
|
+
read_only: false
|
|
94
|
+
},
|
|
95
|
+
add_reaction: {
|
|
96
|
+
description: "Add an emoji reaction to a message",
|
|
97
|
+
parameters: {
|
|
98
|
+
type: "object",
|
|
99
|
+
properties: {
|
|
100
|
+
adapter_name: {type: "string", description: "Adapter name"},
|
|
101
|
+
channel_id: {type: "string", description: "Channel ID"},
|
|
102
|
+
message_id: {type: "string", description: "Message ID"},
|
|
103
|
+
emoji: {type: "string", description: "Emoji name (e.g., 'thumbsup')"}
|
|
104
|
+
},
|
|
105
|
+
required: %w[adapter_name channel_id message_id emoji]
|
|
106
|
+
},
|
|
107
|
+
read_only: false
|
|
108
|
+
},
|
|
109
|
+
remove_reaction: {
|
|
110
|
+
description: "Remove an emoji reaction from a message",
|
|
111
|
+
parameters: {
|
|
112
|
+
type: "object",
|
|
113
|
+
properties: {
|
|
114
|
+
adapter_name: {type: "string", description: "Adapter name"},
|
|
115
|
+
channel_id: {type: "string", description: "Channel ID"},
|
|
116
|
+
message_id: {type: "string", description: "Message ID"},
|
|
117
|
+
emoji: {type: "string", description: "Emoji name"}
|
|
118
|
+
},
|
|
119
|
+
required: %w[adapter_name channel_id message_id emoji]
|
|
120
|
+
},
|
|
121
|
+
read_only: false
|
|
122
|
+
},
|
|
123
|
+
start_typing: {
|
|
124
|
+
description: "Show typing indicator in a channel",
|
|
125
|
+
parameters: {
|
|
126
|
+
type: "object",
|
|
127
|
+
properties: {
|
|
128
|
+
adapter_name: {type: "string", description: "Adapter name"},
|
|
129
|
+
channel_id: {type: "string", description: "Channel ID"},
|
|
130
|
+
thread_id: {type: "string", description: "Thread ID (optional)"}
|
|
131
|
+
},
|
|
132
|
+
required: %w[adapter_name channel_id]
|
|
133
|
+
},
|
|
134
|
+
read_only: false
|
|
135
|
+
}
|
|
136
|
+
}.freeze
|
|
137
|
+
|
|
138
|
+
def initialize(preset: :messenger, require_approval: true)
|
|
139
|
+
@preset = preset.to_sym
|
|
140
|
+
@require_approval = require_approval
|
|
141
|
+
raise ChatSDK::ConfigurationError, "Unknown preset: #{@preset}" unless PRESETS.key?(@preset)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def build
|
|
145
|
+
tool_names = PRESETS[@preset]
|
|
146
|
+
tool_names.each_with_object({}) do |name, tools|
|
|
147
|
+
defn = TOOL_DEFINITIONS[name].dup
|
|
148
|
+
defn[:requires_approval] = @require_approval && !defn[:read_only]
|
|
149
|
+
tools[name] = defn
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChatSDK
|
|
4
|
+
module AI
|
|
5
|
+
class ToolExecutor
|
|
6
|
+
def initialize(chat:)
|
|
7
|
+
@chat = chat
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def execute(tool_name, arguments)
|
|
11
|
+
tool_name = tool_name.to_sym
|
|
12
|
+
raise ChatSDK::Error, "Unknown tool: #{tool_name}" unless ToolBuilder::TOOL_DEFINITIONS.key?(tool_name)
|
|
13
|
+
|
|
14
|
+
args = arguments.transform_keys(&:to_sym)
|
|
15
|
+
adapter_name = args[:adapter_name].to_sym
|
|
16
|
+
|
|
17
|
+
send(:"execute_#{tool_name}", adapter_name, args)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def execute_fetch_messages(adapter_name, args)
|
|
23
|
+
channel = @chat.channel(args[:channel_id], adapter_name: adapter_name)
|
|
24
|
+
messages, _cursor = channel.adapter.fetch_messages(
|
|
25
|
+
channel_id: args[:channel_id],
|
|
26
|
+
thread_id: args[:thread_id],
|
|
27
|
+
limit: args[:limit] || 20
|
|
28
|
+
)
|
|
29
|
+
serialize_messages(messages)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def execute_fetch_thread(adapter_name, args)
|
|
33
|
+
channel = @chat.channel(args[:channel_id], adapter_name: adapter_name)
|
|
34
|
+
messages, _cursor = channel.adapter.fetch_messages(
|
|
35
|
+
channel_id: args[:channel_id],
|
|
36
|
+
thread_id: args[:thread_id]
|
|
37
|
+
)
|
|
38
|
+
serialize_messages(messages)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def execute_post_message(adapter_name, args)
|
|
42
|
+
channel = @chat.channel(args[:channel_id], adapter_name: adapter_name)
|
|
43
|
+
if args[:thread_id]
|
|
44
|
+
thread = channel.thread(args[:thread_id])
|
|
45
|
+
result = thread.post(args[:text])
|
|
46
|
+
else
|
|
47
|
+
result = channel.post(args[:text])
|
|
48
|
+
end
|
|
49
|
+
{id: result.id, text: args[:text]}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def execute_send_direct_message(adapter_name, args)
|
|
53
|
+
dm_channel = @chat.open_dm(args[:user_id], adapter_name: adapter_name)
|
|
54
|
+
result = dm_channel.post(args[:text])
|
|
55
|
+
{id: result.id, channel_id: dm_channel.id}
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def execute_edit_message(adapter_name, args)
|
|
59
|
+
thread = @chat.channel(args[:channel_id], adapter_name: adapter_name).thread(args[:channel_id])
|
|
60
|
+
thread.edit(args[:message_id], args[:text])
|
|
61
|
+
{success: true}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def execute_delete_message(adapter_name, args)
|
|
65
|
+
thread = @chat.channel(args[:channel_id], adapter_name: adapter_name).thread(args[:channel_id])
|
|
66
|
+
thread.delete(args[:message_id])
|
|
67
|
+
{success: true}
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def execute_add_reaction(adapter_name, args)
|
|
71
|
+
thread = @chat.channel(args[:channel_id], adapter_name: adapter_name).thread(args[:channel_id])
|
|
72
|
+
thread.react(args[:message_id], args[:emoji])
|
|
73
|
+
{success: true}
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def execute_remove_reaction(adapter_name, args)
|
|
77
|
+
thread = @chat.channel(args[:channel_id], adapter_name: adapter_name).thread(args[:channel_id])
|
|
78
|
+
thread.unreact(args[:message_id], args[:emoji])
|
|
79
|
+
{success: true}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def execute_start_typing(adapter_name, args)
|
|
83
|
+
adapter = @chat.adapter(adapter_name)
|
|
84
|
+
adapter.start_typing(channel_id: args[:channel_id], thread_id: args[:thread_id])
|
|
85
|
+
{success: true}
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def serialize_messages(messages)
|
|
89
|
+
messages.map { |m| {id: m.id, text: m.text, author: m.author&.name, timestamp: m.timestamp} }
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
data/lib/chat_sdk/ai.rb
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChatSDK
|
|
4
|
+
module AI
|
|
5
|
+
class << self
|
|
6
|
+
def to_ai_messages(messages, include_names: false, &transform)
|
|
7
|
+
Converter.to_ai_messages(messages, include_names: include_names, &transform)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def create_tools(chat:, preset: :messenger, require_approval: true)
|
|
11
|
+
ToolBuilder.new(chat: chat, preset: preset, require_approval: require_approval).build
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/chat_sdk/cards/node.rb
CHANGED
|
@@ -25,14 +25,10 @@ module ChatSDK
|
|
|
25
25
|
def collect_text(nodes = [self])
|
|
26
26
|
nodes.flat_map do |node|
|
|
27
27
|
case node.type
|
|
28
|
-
when :card
|
|
29
|
-
collect_text(node.children)
|
|
30
28
|
when :text
|
|
31
29
|
[node.attributes[:content]]
|
|
32
30
|
when :field
|
|
33
31
|
["#{node.attributes[:label]}: #{node.attributes[:value]}"]
|
|
34
|
-
when :section
|
|
35
|
-
collect_text(node.children)
|
|
36
32
|
when :button, :link_button
|
|
37
33
|
[node.attributes[:text]]
|
|
38
34
|
else
|
data/lib/chat_sdk/dispatcher.rb
CHANGED
|
@@ -60,27 +60,13 @@ module ChatSDK
|
|
|
60
60
|
lock_key = "chat_sdk:lock:#{thread_key}"
|
|
61
61
|
return true if @state.acquire_lock(lock_key, owner: lock_owner, ttl: 30)
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
else
|
|
71
|
-
if @config.on_lock_conflict.respond_to?(:call)
|
|
72
|
-
policy = @config.on_lock_conflict.call(thread_key, event)
|
|
73
|
-
case policy
|
|
74
|
-
when :force
|
|
75
|
-
@state.force_lock(lock_key, owner: lock_owner, ttl: 30)
|
|
76
|
-
true
|
|
77
|
-
else
|
|
78
|
-
false
|
|
79
|
-
end
|
|
80
|
-
else
|
|
81
|
-
false
|
|
82
|
-
end
|
|
83
|
-
end
|
|
63
|
+
policy = @config.on_lock_conflict
|
|
64
|
+
policy = policy.call(thread_key, event) if policy.respond_to?(:call)
|
|
65
|
+
|
|
66
|
+
return false unless policy == :force
|
|
67
|
+
|
|
68
|
+
@state.force_lock(lock_key, owner: lock_owner, ttl: 30)
|
|
69
|
+
true
|
|
84
70
|
end
|
|
85
71
|
|
|
86
72
|
def release_lock(thread_key)
|
|
@@ -109,10 +95,7 @@ module ChatSDK
|
|
|
109
95
|
end
|
|
110
96
|
|
|
111
97
|
def add_thread_to_event(event, thread)
|
|
112
|
-
event.
|
|
113
|
-
unless event.respond_to?(:thread)
|
|
114
|
-
event.define_singleton_method(:thread) { @thread }
|
|
115
|
-
end
|
|
98
|
+
event.thread = thread if event.respond_to?(:thread=)
|
|
116
99
|
end
|
|
117
100
|
end
|
|
118
101
|
end
|
|
@@ -4,6 +4,7 @@ module ChatSDK
|
|
|
4
4
|
module Events
|
|
5
5
|
class Action < Base
|
|
6
6
|
attr_reader :action_id, :value, :user, :thread_id, :channel_id, :trigger_id
|
|
7
|
+
attr_accessor :thread
|
|
7
8
|
|
|
8
9
|
def initialize(action_id:, thread_id:, channel_id:, value: nil, user: nil, trigger_id: nil, **kwargs)
|
|
9
10
|
super(type: :action, **kwargs)
|
|
@@ -4,6 +4,7 @@ module ChatSDK
|
|
|
4
4
|
module Events
|
|
5
5
|
class Reaction < Base
|
|
6
6
|
attr_reader :emoji, :user_id, :message_id, :thread_id, :channel_id, :added
|
|
7
|
+
attr_accessor :thread
|
|
7
8
|
|
|
8
9
|
def initialize(emoji:, user_id:, message_id:, thread_id:, channel_id:, added: true, **kwargs)
|
|
9
10
|
super(type: :reaction, **kwargs)
|
|
@@ -4,6 +4,7 @@ module ChatSDK
|
|
|
4
4
|
module Events
|
|
5
5
|
class SlashCommand < Base
|
|
6
6
|
attr_reader :command, :text, :user_id, :channel_id, :trigger_id
|
|
7
|
+
attr_accessor :thread
|
|
7
8
|
|
|
8
9
|
def initialize(command:, user_id:, channel_id:, text: "", trigger_id: nil, **kwargs)
|
|
9
10
|
super(type: :slash_command, **kwargs)
|
data/lib/chat_sdk/thread.rb
CHANGED
|
@@ -61,6 +61,10 @@ module ChatSDK
|
|
|
61
61
|
adapter.remove_reaction(channel_id: channel_id, message_id: message_id, emoji: emoji)
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
+
def post_ai_stream(enumerable, placeholder: "Thinking...")
|
|
65
|
+
ChatSDK::AI::StreamHandler.stream_to_thread(self, enumerable, placeholder: placeholder)
|
|
66
|
+
end
|
|
67
|
+
|
|
64
68
|
def upload(io:, filename:, comment: nil)
|
|
65
69
|
adapter.upload_file(channel_id: channel_id, io: io, filename: filename, thread_id: id, comment: comment)
|
|
66
70
|
end
|
data/lib/chat_sdk/version.rb
CHANGED
data/lib/chat_sdk.rb
CHANGED
|
@@ -9,7 +9,7 @@ module ChatSDK
|
|
|
9
9
|
def loader
|
|
10
10
|
@loader ||= begin
|
|
11
11
|
loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
|
|
12
|
-
loader.inflector.inflect("chat_sdk" => "ChatSDK")
|
|
12
|
+
loader.inflector.inflect("chat_sdk" => "ChatSDK", "ai" => "AI")
|
|
13
13
|
loader.ignore("#{__dir__}/chat_sdk/version.rb")
|
|
14
14
|
loader.ignore("#{__dir__}/chat_sdk/errors.rb")
|
|
15
15
|
loader.setup
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: chat_sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rootly
|
|
@@ -34,6 +34,11 @@ files:
|
|
|
34
34
|
- lib/chat_sdk.rb
|
|
35
35
|
- lib/chat_sdk/adapter/base.rb
|
|
36
36
|
- lib/chat_sdk/adapter/capabilities.rb
|
|
37
|
+
- lib/chat_sdk/ai.rb
|
|
38
|
+
- lib/chat_sdk/ai/converter.rb
|
|
39
|
+
- lib/chat_sdk/ai/stream_handler.rb
|
|
40
|
+
- lib/chat_sdk/ai/tool_builder.rb
|
|
41
|
+
- lib/chat_sdk/ai/tool_executor.rb
|
|
37
42
|
- lib/chat_sdk/author.rb
|
|
38
43
|
- lib/chat_sdk/cards/actions_context.rb
|
|
39
44
|
- lib/chat_sdk/cards/builder.rb
|