mistri 0.1.0 → 0.2.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.
@@ -45,12 +45,53 @@ module Mistri
45
45
  @mutex.synchronize { stream_locked(path, body, headers, signal, &block) }
46
46
  end
47
47
 
48
+ # POST for Streamable-HTTP endpoints (the MCP shape) that answer either
49
+ # a JSON body or an SSE stream: yields each JSON record either way and
50
+ # returns the response headers, downcased. Retries only a dead idle
51
+ # socket that failed before any response started, so a side-effecting
52
+ # call can never run twice.
53
+ def post_either(path, body:, headers: {}, &block)
54
+ @mutex.synchronize do
55
+ retried = false
56
+ begin
57
+ started = false
58
+ response_headers = nil
59
+ connection.request(build_request(path, body, headers, streaming: true)) do |response|
60
+ started = true
61
+ raise_for_status(response)
62
+ response_headers = response.to_hash.transform_values(&:first)
63
+ read_either(response, &block)
64
+ end
65
+ response_headers
66
+ rescue IOError, SocketError, SystemCallError, Timeout::Error => e
67
+ teardown
68
+ if started || retried || e.is_a?(Timeout::Error)
69
+ raise ProviderError, "connection failed: #{e.message}"
70
+ end
71
+
72
+ retried = true
73
+ retry
74
+ end
75
+ end
76
+ end
77
+
48
78
  def close
49
79
  @mutex.synchronize { teardown }
50
80
  end
51
81
 
52
82
  private
53
83
 
84
+ def read_either(response, &block)
85
+ if response["content-type"].to_s.include?("text/event-stream")
86
+ sse = SSE.new
87
+ response.read_body { |chunk| sse.feed(chunk, &block) }
88
+ sse.finish(&block)
89
+ else
90
+ raw = response.read_body
91
+ block.call(JSON.parse(raw)) unless raw.to_s.strip.empty?
92
+ end
93
+ end
94
+
54
95
  def stream_locked(path, body, headers, signal, &block)
55
96
  retried = false
56
97
  begin
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mistri
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/mistri.rb CHANGED
@@ -28,6 +28,7 @@ require_relative "mistri/skills"
28
28
  require_relative "mistri/tool_executor"
29
29
  require_relative "mistri/budget"
30
30
  require_relative "mistri/retry_policy"
31
+ require_relative "mistri/reminder"
31
32
  require_relative "mistri/compaction"
32
33
  require_relative "mistri/stores/memory"
33
34
  require_relative "mistri/stores/jsonl"
@@ -36,6 +37,7 @@ require_relative "mistri/compactor"
36
37
  require_relative "mistri/result"
37
38
  require_relative "mistri/agent"
38
39
  require_relative "mistri/sub_agent"
40
+ require_relative "mistri/mcp"
39
41
  require_relative "mistri/sinks/action_cable"
40
42
  require_relative "mistri/sinks/sse"
41
43
  require_relative "mistri/sinks/coalesced"
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mistri
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muhammad Ahmed Cheema
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-07-05 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: 'Mistri (مستری) is the fixer: an agent harness that lives inside your
14
13
  app. Durable sessions in your own database, streaming, tools, fire-and-forget human
15
14
  approval, steering, compaction, structured output, skills, and sub-agents, across
16
15
  Anthropic, OpenAI, and Gemini, with zero runtime dependencies.'
17
- email:
18
16
  executables: []
19
17
  extensions: []
20
18
  extra_rdoc_files: []
@@ -26,6 +24,9 @@ files:
26
24
  - lib/generators/mistri/install/install_generator.rb
27
25
  - lib/generators/mistri/install/templates/migration.rb.tt
28
26
  - lib/generators/mistri/install/templates/model.rb.tt
27
+ - lib/generators/mistri/mcp/mcp_generator.rb
28
+ - lib/generators/mistri/mcp/templates/migration.rb.tt
29
+ - lib/generators/mistri/mcp/templates/model.rb.tt
29
30
  - lib/mistri.rb
30
31
  - lib/mistri/abort_signal.rb
31
32
  - lib/mistri/agent.rb
@@ -36,6 +37,10 @@ files:
36
37
  - lib/mistri/edit.rb
37
38
  - lib/mistri/errors.rb
38
39
  - lib/mistri/event.rb
40
+ - lib/mistri/mcp.rb
41
+ - lib/mistri/mcp/client.rb
42
+ - lib/mistri/mcp/oauth.rb
43
+ - lib/mistri/mcp/wires.rb
39
44
  - lib/mistri/memory.rb
40
45
  - lib/mistri/message.rb
41
46
  - lib/mistri/models.rb
@@ -50,6 +55,7 @@ files:
50
55
  - lib/mistri/providers/openai.rb
51
56
  - lib/mistri/providers/openai/assembler.rb
52
57
  - lib/mistri/providers/openai/serializer.rb
58
+ - lib/mistri/reminder.rb
53
59
  - lib/mistri/result.rb
54
60
  - lib/mistri/retry_policy.rb
55
61
  - lib/mistri/schema.rb
@@ -92,7 +98,8 @@ metadata:
92
98
  source_code_uri: https://github.com/mcheemaa/mistri
93
99
  changelog_uri: https://github.com/mcheemaa/mistri/blob/main/CHANGELOG.md
94
100
  rubygems_mfa_required: 'true'
95
- post_install_message:
101
+ documentation_uri: https://rubydoc.info/gems/mistri
102
+ bug_tracker_uri: https://github.com/mcheemaa/mistri/issues
96
103
  rdoc_options: []
97
104
  require_paths:
98
105
  - lib
@@ -107,8 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
114
  - !ruby/object:Gem::Version
108
115
  version: '0'
109
116
  requirements: []
110
- rubygems_version: 3.5.22
111
- signing_key:
117
+ rubygems_version: 3.6.9
112
118
  specification_version: 4
113
119
  summary: The agent harness for Ruby applications.
114
120
  test_files: []