langgraph-platform 0.1.0

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.
@@ -0,0 +1,49 @@
1
+ module LanggraphPlatform
2
+ module Errors
3
+ class APIError < StandardError
4
+ attr_reader :message, :status_code
5
+
6
+ def initialize(message, status_code = nil)
7
+ @message = message
8
+ @status_code = status_code
9
+ super(message)
10
+ end
11
+ end
12
+
13
+ class BadRequestError < APIError
14
+ def initialize(message)
15
+ super(message, 400)
16
+ end
17
+ end
18
+
19
+ class UnauthorizedError < APIError
20
+ def initialize(message)
21
+ super(message, 401)
22
+ end
23
+ end
24
+
25
+ class NotFoundError < APIError
26
+ def initialize(message)
27
+ super(message, 404)
28
+ end
29
+ end
30
+
31
+ class ConflictError < APIError
32
+ def initialize(message)
33
+ super(message, 409)
34
+ end
35
+ end
36
+
37
+ class ValidationError < APIError
38
+ def initialize(message)
39
+ super(message, 422)
40
+ end
41
+ end
42
+
43
+ class ServerError < APIError
44
+ def initialize(message)
45
+ super(message, 500)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,48 @@
1
+ module LanggraphPlatform
2
+ module Models
3
+ class Assistant
4
+ attr_reader :assistant_id, :graph_id, :config, :created_at, :updated_at,
5
+ :metadata, :version, :name, :description
6
+
7
+ def initialize(attributes)
8
+ @assistant_id = attributes['assistant_id']
9
+ @graph_id = attributes['graph_id']
10
+ @config = attributes['config']
11
+ @created_at = parse_time(attributes['created_at'])
12
+ @updated_at = parse_time(attributes['updated_at'])
13
+ @metadata = attributes['metadata'] || {}
14
+ @version = attributes['version']
15
+ @name = attributes['name']
16
+ @description = attributes['description']
17
+ end
18
+
19
+ def to_h
20
+ {
21
+ assistant_id: @assistant_id,
22
+ graph_id: @graph_id,
23
+ config: @config,
24
+ created_at: @created_at,
25
+ updated_at: @updated_at,
26
+ metadata: @metadata,
27
+ version: @version,
28
+ name: @name,
29
+ description: @description
30
+ }
31
+ end
32
+
33
+ def to_json(*args)
34
+ to_h.to_json(*args)
35
+ end
36
+
37
+ private
38
+
39
+ def parse_time(time_string)
40
+ return nil if time_string.nil?
41
+
42
+ Time.parse(time_string)
43
+ rescue ArgumentError
44
+ nil
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,42 @@
1
+ module LanggraphPlatform
2
+ module Models
3
+ class Checkpoint
4
+ attr_reader :checkpoint_id, :thread_id, :checkpoint_ns, :checkpoint_map,
5
+ :parent_checkpoint_id, :created_at
6
+
7
+ def initialize(attributes)
8
+ @checkpoint_id = attributes['checkpoint_id']
9
+ @thread_id = attributes['thread_id']
10
+ @checkpoint_ns = attributes['checkpoint_ns']
11
+ @checkpoint_map = attributes['checkpoint_map']
12
+ @parent_checkpoint_id = attributes['parent_checkpoint_id']
13
+ @created_at = parse_time(attributes['created_at'])
14
+ end
15
+
16
+ def to_h
17
+ {
18
+ checkpoint_id: @checkpoint_id,
19
+ thread_id: @thread_id,
20
+ checkpoint_ns: @checkpoint_ns,
21
+ checkpoint_map: @checkpoint_map,
22
+ parent_checkpoint_id: @parent_checkpoint_id,
23
+ created_at: @created_at
24
+ }
25
+ end
26
+
27
+ def to_json(*args)
28
+ to_h.to_json(*args)
29
+ end
30
+
31
+ private
32
+
33
+ def parse_time(time_string)
34
+ return nil if time_string.nil?
35
+
36
+ Time.parse(time_string)
37
+ rescue ArgumentError
38
+ nil
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,56 @@
1
+ module LanggraphPlatform
2
+ module Models
3
+ class Cron
4
+ attr_reader :cron_id, :assistant_id, :thread_id, :schedule, :payload,
5
+ :created_at, :updated_at, :next_run_time, :enabled
6
+
7
+ def initialize(attributes)
8
+ @cron_id = attributes['cron_id']
9
+ @assistant_id = attributes['assistant_id']
10
+ @thread_id = attributes['thread_id']
11
+ @schedule = attributes['schedule']
12
+ @payload = attributes['payload']
13
+ @created_at = parse_time(attributes['created_at'])
14
+ @updated_at = parse_time(attributes['updated_at'])
15
+ @next_run_time = parse_time(attributes['next_run_time'])
16
+ @enabled = attributes['enabled']
17
+ end
18
+
19
+ def enabled?
20
+ @enabled == true
21
+ end
22
+
23
+ def disabled?
24
+ !enabled?
25
+ end
26
+
27
+ def to_h
28
+ {
29
+ cron_id: @cron_id,
30
+ assistant_id: @assistant_id,
31
+ thread_id: @thread_id,
32
+ schedule: @schedule,
33
+ payload: @payload,
34
+ created_at: @created_at,
35
+ updated_at: @updated_at,
36
+ next_run_time: @next_run_time,
37
+ enabled: @enabled
38
+ }
39
+ end
40
+
41
+ def to_json(*args)
42
+ to_h.to_json(*args)
43
+ end
44
+
45
+ private
46
+
47
+ def parse_time(time_string)
48
+ return nil if time_string.nil?
49
+
50
+ Time.parse(time_string)
51
+ rescue ArgumentError
52
+ nil
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,72 @@
1
+ module LanggraphPlatform
2
+ module Models
3
+ class Run
4
+ attr_reader :run_id, :thread_id, :assistant_id, :created_at, :updated_at,
5
+ :status, :metadata, :kwargs, :multitask_strategy
6
+
7
+ def initialize(attributes)
8
+ @run_id = attributes['run_id']
9
+ @thread_id = attributes['thread_id']
10
+ @assistant_id = attributes['assistant_id']
11
+ @created_at = parse_time(attributes['created_at'])
12
+ @updated_at = parse_time(attributes['updated_at'])
13
+ @status = attributes['status']
14
+ @metadata = attributes['metadata'] || {}
15
+ @kwargs = attributes['kwargs']
16
+ @multitask_strategy = attributes['multitask_strategy']
17
+ end
18
+
19
+ def pending?
20
+ @status == 'pending'
21
+ end
22
+
23
+ def running?
24
+ @status == 'running'
25
+ end
26
+
27
+ def success?
28
+ @status == 'success'
29
+ end
30
+
31
+ def error?
32
+ @status == 'error'
33
+ end
34
+
35
+ def timeout?
36
+ @status == 'timeout'
37
+ end
38
+
39
+ def interrupted?
40
+ @status == 'interrupted'
41
+ end
42
+
43
+ def to_h
44
+ {
45
+ run_id: @run_id,
46
+ thread_id: @thread_id,
47
+ assistant_id: @assistant_id,
48
+ created_at: @created_at,
49
+ updated_at: @updated_at,
50
+ status: @status,
51
+ metadata: @metadata,
52
+ kwargs: @kwargs,
53
+ multitask_strategy: @multitask_strategy
54
+ }
55
+ end
56
+
57
+ def to_json(*args)
58
+ to_h.to_json(*args)
59
+ end
60
+
61
+ private
62
+
63
+ def parse_time(time_string)
64
+ return nil if time_string.nil?
65
+
66
+ Time.parse(time_string)
67
+ rescue ArgumentError
68
+ nil
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,39 @@
1
+ module LanggraphPlatform
2
+ module Models
3
+ class StoreItem
4
+ attr_reader :namespace, :key, :value, :created_at, :updated_at
5
+
6
+ def initialize(attributes)
7
+ @namespace = attributes['namespace']
8
+ @key = attributes['key']
9
+ @value = attributes['value']
10
+ @created_at = parse_time(attributes['created_at'])
11
+ @updated_at = parse_time(attributes['updated_at'])
12
+ end
13
+
14
+ def to_h
15
+ {
16
+ namespace: @namespace,
17
+ key: @key,
18
+ value: @value,
19
+ created_at: @created_at,
20
+ updated_at: @updated_at
21
+ }
22
+ end
23
+
24
+ def to_json(*args)
25
+ to_h.to_json(*args)
26
+ end
27
+
28
+ private
29
+
30
+ def parse_time(time_string)
31
+ return nil if time_string.nil?
32
+
33
+ Time.parse(time_string)
34
+ rescue ArgumentError
35
+ nil
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,57 @@
1
+ module LanggraphPlatform
2
+ module Models
3
+ class Thread
4
+ attr_reader :thread_id, :created_at, :updated_at, :metadata, :status, :values
5
+
6
+ def initialize(attributes)
7
+ @thread_id = attributes['thread_id']
8
+ @created_at = parse_time(attributes['created_at'])
9
+ @updated_at = parse_time(attributes['updated_at'])
10
+ @metadata = attributes['metadata'] || {}
11
+ @status = attributes['status']
12
+ @values = attributes['values']
13
+ end
14
+
15
+ def idle?
16
+ @status == 'idle'
17
+ end
18
+
19
+ def busy?
20
+ @status == 'busy'
21
+ end
22
+
23
+ def interrupted?
24
+ @status == 'interrupted'
25
+ end
26
+
27
+ def error?
28
+ @status == 'error'
29
+ end
30
+
31
+ def to_h
32
+ {
33
+ thread_id: @thread_id,
34
+ created_at: @created_at,
35
+ updated_at: @updated_at,
36
+ metadata: @metadata,
37
+ status: @status,
38
+ values: @values
39
+ }
40
+ end
41
+
42
+ def to_json(*args)
43
+ to_h.to_json(*args)
44
+ end
45
+
46
+ private
47
+
48
+ def parse_time(time_string)
49
+ return nil if time_string.nil?
50
+
51
+ Time.parse(time_string)
52
+ rescue ArgumentError
53
+ nil
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,41 @@
1
+ module LanggraphPlatform
2
+ module Models
3
+ class ThreadState
4
+ attr_reader :values, :next, :checkpoint, :metadata, :created_at, :parent_checkpoint
5
+
6
+ def initialize(attributes)
7
+ @values = attributes['values']
8
+ @next = attributes['next']
9
+ @checkpoint = attributes['checkpoint']
10
+ @metadata = attributes['metadata'] || {}
11
+ @created_at = parse_time(attributes['created_at'])
12
+ @parent_checkpoint = attributes['parent_checkpoint']
13
+ end
14
+
15
+ def to_h
16
+ {
17
+ values: @values,
18
+ next: @next,
19
+ checkpoint: @checkpoint,
20
+ metadata: @metadata,
21
+ created_at: @created_at,
22
+ parent_checkpoint: @parent_checkpoint
23
+ }
24
+ end
25
+
26
+ def to_json(*args)
27
+ to_h.to_json(*args)
28
+ end
29
+
30
+ private
31
+
32
+ def parse_time(time_string)
33
+ return nil if time_string.nil?
34
+
35
+ Time.parse(time_string)
36
+ rescue ArgumentError
37
+ nil
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,65 @@
1
+ module LanggraphPlatform
2
+ module Resources
3
+ class Assistants < BaseResource
4
+ def create(**params)
5
+ params[:config] ||= {}
6
+ params[:metadata] ||= {}
7
+ body = compact_params(params)
8
+ response = @client.post('/assistants', body)
9
+ Models::Assistant.new(response)
10
+ end
11
+
12
+ def find(assistant_id)
13
+ response = @client.get("/assistants/#{assistant_id}")
14
+ Models::Assistant.new(response)
15
+ end
16
+
17
+ def update(assistant_id, **params)
18
+ body = compact_params(params)
19
+ response = @client.patch("/assistants/#{assistant_id}", body)
20
+ Models::Assistant.new(response)
21
+ end
22
+
23
+ def delete(assistant_id) # rubocop:disable Naming/PredicateMethod
24
+ @client.delete("/assistants/#{assistant_id}")
25
+ true
26
+ end
27
+
28
+ def search(**params)
29
+ params[:metadata] ||= {}
30
+ params[:limit] ||= 10
31
+ params[:offset] ||= 0
32
+ body = compact_params(params)
33
+ response = @client.post('/assistants/search', body)
34
+ response.map { |assistant_data| Models::Assistant.new(assistant_data) }
35
+ end
36
+
37
+ def graph(assistant_id, **params)
38
+ params[:xray] ||= false
39
+ query_params = compact_params(params)
40
+ @client.get("/assistants/#{assistant_id}/graph", query_params)
41
+ end
42
+
43
+ def subgraphs(assistant_id, **params)
44
+ params[:recurse] ||= false
45
+ query_params = compact_params(params)
46
+ @client.get("/assistants/#{assistant_id}/subgraphs", query_params)
47
+ end
48
+
49
+ def schemas(assistant_id)
50
+ @client.get("/assistants/#{assistant_id}/schemas")
51
+ end
52
+
53
+ def versions(assistant_id)
54
+ response = @client.post("/assistants/#{assistant_id}/versions")
55
+ response.map { |assistant_data| Models::Assistant.new(assistant_data) }
56
+ end
57
+
58
+ def set_latest_version(assistant_id, **params)
59
+ body = compact_params(params)
60
+ response = @client.post("/assistants/#{assistant_id}/latest", body)
61
+ Models::Assistant.new(response)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,27 @@
1
+ module LanggraphPlatform
2
+ module Resources
3
+ class BaseResource
4
+ def initialize(client)
5
+ @client = client
6
+ end
7
+
8
+ private
9
+
10
+ attr_reader :client
11
+
12
+ def handle_response(response, model_class = nil)
13
+ return response unless model_class
14
+
15
+ if response.is_a?(Array)
16
+ response.map { |item| model_class.new(item) }
17
+ else
18
+ model_class.new(response)
19
+ end
20
+ end
21
+
22
+ def compact_params(params)
23
+ params.compact
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,54 @@
1
+ module LanggraphPlatform
2
+ module Resources
3
+ class Crons < BaseResource
4
+ def create(**params)
5
+ params[:payload] ||= {}
6
+ body = compact_params(params)
7
+ response = @client.post('/crons', body)
8
+ Models::Cron.new(response)
9
+ end
10
+
11
+ def find(cron_id)
12
+ response = @client.get("/crons/#{cron_id}")
13
+ Models::Cron.new(response)
14
+ end
15
+
16
+ def update(cron_id, **params)
17
+ body = compact_params(params)
18
+ response = @client.patch("/crons/#{cron_id}", body)
19
+ Models::Cron.new(response)
20
+ end
21
+
22
+ def delete(cron_id) # rubocop:disable Naming/PredicateMethod
23
+ @client.delete("/crons/#{cron_id}")
24
+ true
25
+ end
26
+
27
+ def list(**params)
28
+ params[:limit] ||= 10
29
+ params[:offset] ||= 0
30
+ query_params = compact_params(params)
31
+ response = @client.get('/crons', query_params)
32
+ response.map { |cron_data| Models::Cron.new(cron_data) }
33
+ end
34
+
35
+ def search(**params)
36
+ params[:limit] ||= 10
37
+ params[:offset] ||= 0
38
+ body = compact_params(params)
39
+ response = @client.post('/crons/search', body)
40
+ response.map { |cron_data| Models::Cron.new(cron_data) }
41
+ end
42
+
43
+ def enable(cron_id) # rubocop:disable Naming/PredicateMethod
44
+ @client.post("/crons/#{cron_id}/enable")
45
+ true
46
+ end
47
+
48
+ def disable(cron_id) # rubocop:disable Naming/PredicateMethod
49
+ @client.post("/crons/#{cron_id}/disable")
50
+ true
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,54 @@
1
+ module LanggraphPlatform
2
+ module Resources
3
+ class Mcp < BaseResource
4
+ def call_tool(**params)
5
+ params[:arguments] ||= {}
6
+ body = compact_params(params)
7
+ @client.post('/mcp/tools/call', body)
8
+ end
9
+
10
+ def list_tools
11
+ @client.get('/mcp/tools')
12
+ end
13
+
14
+ def get_tool(tool_name)
15
+ @client.get("/mcp/tools/#{tool_name}")
16
+ end
17
+
18
+ def list_resources
19
+ @client.get('/mcp/resources')
20
+ end
21
+
22
+ def get_resource(**params)
23
+ query_params = compact_params(params)
24
+ @client.get('/mcp/resources/get', query_params)
25
+ end
26
+
27
+ def read_resource(**params)
28
+ query_params = compact_params(params)
29
+ @client.get('/mcp/resources/read', query_params)
30
+ end
31
+
32
+ def list_prompts
33
+ @client.get('/mcp/prompts')
34
+ end
35
+
36
+ def get_prompt(**params)
37
+ params[:arguments] ||= {}
38
+ body = compact_params(params)
39
+ @client.post('/mcp/prompts/get', body)
40
+ end
41
+
42
+ def complete_prompt(**params)
43
+ params[:arguments] ||= {}
44
+ body = compact_params(params)
45
+ @client.post('/mcp/prompts/complete', body)
46
+ end
47
+
48
+ def send_log(**params)
49
+ body = compact_params(params)
50
+ @client.post('/mcp/logging/log', body)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,84 @@
1
+ module LanggraphPlatform
2
+ module Resources
3
+ class Runs < BaseResource
4
+ def create(thread_id, **params)
5
+ body = compact_params(params)
6
+ response = @client.post("/threads/#{thread_id}/runs", body)
7
+ Models::Run.new(response)
8
+ end
9
+
10
+ def stream(thread_id, **params, &block)
11
+ params[:stream_mode] = Array(params[:stream_mode] || ['values'])
12
+ body = compact_params(params)
13
+ @client.stream("/threads/#{thread_id}/runs/stream", body, &block)
14
+ end
15
+
16
+ def wait(thread_id, **params)
17
+ body = compact_params(params)
18
+ @client.post("/threads/#{thread_id}/runs/wait", body)
19
+ end
20
+
21
+ def find(thread_id, run_id)
22
+ response = @client.get("/threads/#{thread_id}/runs/#{run_id}")
23
+ Models::Run.new(response)
24
+ end
25
+
26
+ def list(thread_id, **params)
27
+ params[:limit] ||= 10
28
+ params[:offset] ||= 0
29
+ query_params = compact_params(params)
30
+ response = @client.get("/threads/#{thread_id}/runs", query_params)
31
+ response.map { |run_data| Models::Run.new(run_data) }
32
+ end
33
+
34
+ def cancel(thread_id, run_id, **params)
35
+ params[:wait] ||= false
36
+ params[:action] ||= 'interrupt'
37
+ body = compact_params(params)
38
+ @client.post("/threads/#{thread_id}/runs/#{run_id}/cancel", body)
39
+ end
40
+
41
+ def join(thread_id, run_id, **params)
42
+ params[:cancel_on_disconnect] ||= false
43
+ query_params = compact_params(params)
44
+ @client.get("/threads/#{thread_id}/runs/#{run_id}/join", query_params)
45
+ end
46
+
47
+ def join_stream(thread_id, run_id, &block)
48
+ @client.stream("/threads/#{thread_id}/runs/#{run_id}/stream", &block)
49
+ end
50
+
51
+ def delete(thread_id, run_id) # rubocop:disable Naming/PredicateMethod
52
+ @client.delete("/threads/#{thread_id}/runs/#{run_id}")
53
+ true
54
+ end
55
+
56
+ # Stateless runs
57
+ def create_stateless(**params)
58
+ body = compact_params(params)
59
+ @client.post('/runs', body)
60
+ end
61
+
62
+ def stream_stateless(**params, &block)
63
+ params[:stream_mode] = Array(params[:stream_mode] || ['values'])
64
+ body = compact_params(params)
65
+ @client.stream('/runs/stream', body, &block)
66
+ end
67
+
68
+ def wait_stateless(**params)
69
+ body = compact_params(params)
70
+ @client.post('/runs/wait', body)
71
+ end
72
+
73
+ def create_batch(runs)
74
+ @client.post('/runs/batch', runs)
75
+ end
76
+
77
+ def cancel_multiple(**params)
78
+ params[:action] ||= 'interrupt'
79
+ body = compact_params(params)
80
+ @client.post('/runs/cancel', body)
81
+ end
82
+ end
83
+ end
84
+ end