mistri 0.0.3 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +162 -0
- data/README.md +314 -3
- data/lib/generators/mistri/install/install_generator.rb +54 -0
- data/lib/generators/mistri/install/templates/migration.rb.tt +14 -0
- data/lib/generators/mistri/install/templates/model.rb.tt +4 -0
- data/lib/mistri/abort_signal.rb +63 -0
- data/lib/mistri/agent.rb +340 -0
- data/lib/mistri/budget.rb +29 -0
- data/lib/mistri/compaction.rb +78 -0
- data/lib/mistri/compactor.rb +182 -0
- data/lib/mistri/content.rb +89 -0
- data/lib/mistri/edit.rb +238 -0
- data/lib/mistri/errors.rb +94 -0
- data/lib/mistri/event.rb +50 -0
- data/lib/mistri/memory.rb +26 -0
- data/lib/mistri/message.rb +90 -0
- data/lib/mistri/models.rb +43 -0
- data/lib/mistri/partial_json.rb +210 -0
- data/lib/mistri/providers/anthropic/assembler.rb +205 -0
- data/lib/mistri/providers/anthropic/serializer.rb +106 -0
- data/lib/mistri/providers/anthropic.rb +106 -0
- data/lib/mistri/providers/fake.rb +109 -0
- data/lib/mistri/providers/gemini/assembler.rb +163 -0
- data/lib/mistri/providers/gemini/serializer.rb +109 -0
- data/lib/mistri/providers/gemini.rb +73 -0
- data/lib/mistri/providers/openai/assembler.rb +205 -0
- data/lib/mistri/providers/openai/serializer.rb +104 -0
- data/lib/mistri/providers/openai.rb +72 -0
- data/lib/mistri/result.rb +30 -0
- data/lib/mistri/retry_policy.rb +47 -0
- data/lib/mistri/schema.rb +162 -0
- data/lib/mistri/session.rb +124 -0
- data/lib/mistri/sinks/action_cable.rb +30 -0
- data/lib/mistri/sinks/coalesced.rb +61 -0
- data/lib/mistri/sinks/sse.rb +26 -0
- data/lib/mistri/skill.rb +15 -0
- data/lib/mistri/skills.rb +81 -0
- data/lib/mistri/sse.rb +50 -0
- data/lib/mistri/stop_reason.rb +25 -0
- data/lib/mistri/stores/active_record.rb +47 -0
- data/lib/mistri/stores/jsonl.rb +37 -0
- data/lib/mistri/stores/memory.rb +22 -0
- data/lib/mistri/sub_agent.rb +211 -0
- data/lib/mistri/tool.rb +94 -0
- data/lib/mistri/tool_call.rb +18 -0
- data/lib/mistri/tool_context.rb +15 -0
- data/lib/mistri/tool_executor.rb +66 -0
- data/lib/mistri/tool_result.rb +23 -0
- data/lib/mistri/tools/edit_file.rb +37 -0
- data/lib/mistri/tools/find_in_file.rb +36 -0
- data/lib/mistri/tools/list_files.rb +16 -0
- data/lib/mistri/tools/read_file.rb +38 -0
- data/lib/mistri/tools/read_memory.rb +16 -0
- data/lib/mistri/tools/update_memory.rb +22 -0
- data/lib/mistri/tools/write_file.rb +20 -0
- data/lib/mistri/tools.rb +50 -0
- data/lib/mistri/transport.rb +187 -0
- data/lib/mistri/usage.rb +79 -0
- data/lib/mistri/version.rb +1 -1
- data/lib/mistri/workspace/active_record.rb +47 -0
- data/lib/mistri/workspace/directory.rb +52 -0
- data/lib/mistri/workspace/memory.rb +40 -0
- data/lib/mistri/workspace/single.rb +48 -0
- data/lib/mistri.rb +87 -0
- metadata +68 -5
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mistri
|
|
4
|
+
module Workspace
|
|
5
|
+
# One document living wherever the host says: a column on a record, a
|
|
6
|
+
# cache key, anything readable and writable. This is the shape of an
|
|
7
|
+
# agent that edits one page:
|
|
8
|
+
#
|
|
9
|
+
# workspace = Mistri::Workspace::Single.new(
|
|
10
|
+
# path: "page.html",
|
|
11
|
+
# read: -> { page.reload.draft_html },
|
|
12
|
+
# write: ->(html) { page.update!(draft_html: html) }
|
|
13
|
+
# )
|
|
14
|
+
#
|
|
15
|
+
# The document tools then read and edit that column like any document.
|
|
16
|
+
class Single
|
|
17
|
+
def initialize(read:, write:, path: "document")
|
|
18
|
+
@path = path.to_s
|
|
19
|
+
@read = read
|
|
20
|
+
@write = write
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def read(path)
|
|
24
|
+
path.to_s == @path ? @read.call : nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def write(path, content)
|
|
28
|
+
raise SchemaError, "this workspace holds only #{@path.inspect}" unless path.to_s == @path
|
|
29
|
+
|
|
30
|
+
@write.call(content.to_s)
|
|
31
|
+
nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def delete(path)
|
|
35
|
+
if path.to_s == @path
|
|
36
|
+
raise SchemaError,
|
|
37
|
+
"#{@path.inspect} cannot be deleted, only rewritten"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
nil
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def list(prefix = nil)
|
|
44
|
+
prefix.nil? || @path.start_with?(prefix.to_s) ? [@path] : []
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
data/lib/mistri.rb
CHANGED
|
@@ -1,7 +1,94 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "mistri/version"
|
|
4
|
+
require_relative "mistri/errors"
|
|
5
|
+
require_relative "mistri/stop_reason"
|
|
6
|
+
require_relative "mistri/usage"
|
|
7
|
+
require_relative "mistri/models"
|
|
8
|
+
require_relative "mistri/tool_call"
|
|
9
|
+
require_relative "mistri/content"
|
|
10
|
+
require_relative "mistri/message"
|
|
11
|
+
require_relative "mistri/event"
|
|
12
|
+
require_relative "mistri/abort_signal"
|
|
13
|
+
require_relative "mistri/sse"
|
|
14
|
+
require_relative "mistri/partial_json"
|
|
15
|
+
require_relative "mistri/transport"
|
|
16
|
+
require_relative "mistri/schema"
|
|
17
|
+
require_relative "mistri/edit"
|
|
18
|
+
require_relative "mistri/tool_context"
|
|
19
|
+
require_relative "mistri/tool_result"
|
|
20
|
+
require_relative "mistri/tool"
|
|
21
|
+
require_relative "mistri/workspace/memory"
|
|
22
|
+
require_relative "mistri/workspace/directory"
|
|
23
|
+
require_relative "mistri/workspace/single"
|
|
24
|
+
require_relative "mistri/memory"
|
|
25
|
+
require_relative "mistri/tools"
|
|
26
|
+
require_relative "mistri/skill"
|
|
27
|
+
require_relative "mistri/skills"
|
|
28
|
+
require_relative "mistri/tool_executor"
|
|
29
|
+
require_relative "mistri/budget"
|
|
30
|
+
require_relative "mistri/retry_policy"
|
|
31
|
+
require_relative "mistri/compaction"
|
|
32
|
+
require_relative "mistri/stores/memory"
|
|
33
|
+
require_relative "mistri/stores/jsonl"
|
|
34
|
+
require_relative "mistri/session"
|
|
35
|
+
require_relative "mistri/compactor"
|
|
36
|
+
require_relative "mistri/result"
|
|
37
|
+
require_relative "mistri/agent"
|
|
38
|
+
require_relative "mistri/sub_agent"
|
|
39
|
+
require_relative "mistri/sinks/action_cable"
|
|
40
|
+
require_relative "mistri/sinks/sse"
|
|
41
|
+
require_relative "mistri/sinks/coalesced"
|
|
42
|
+
require_relative "mistri/providers/fake"
|
|
43
|
+
require_relative "mistri/providers/anthropic"
|
|
44
|
+
require_relative "mistri/providers/openai"
|
|
45
|
+
require_relative "mistri/providers/gemini"
|
|
4
46
|
|
|
5
47
|
# Mistri (مستری): the fixer. An agent harness for Ruby applications.
|
|
6
48
|
module Mistri
|
|
49
|
+
PROVIDERS = { anthropic: Providers::Anthropic, openai: Providers::OpenAI,
|
|
50
|
+
gemini: Providers::Gemini }.freeze
|
|
51
|
+
API_KEY_ENV = { anthropic: "ANTHROPIC_API_KEY", openai: "OPENAI_API_KEY",
|
|
52
|
+
gemini: "GEMINI_API_KEY" }.freeze
|
|
53
|
+
|
|
54
|
+
module_function
|
|
55
|
+
|
|
56
|
+
# Build a provider for a model, inferring which one from the model id and
|
|
57
|
+
# reading its key from the environment unless one is passed.
|
|
58
|
+
#
|
|
59
|
+
# Mistri.provider("claude-opus-4-8")
|
|
60
|
+
# Mistri.provider("gpt-5.5", api_key: key, reasoning: { effort: "high" })
|
|
61
|
+
def provider(model, api_key: nil, **)
|
|
62
|
+
name = provider_name(model)
|
|
63
|
+
klass = PROVIDERS.fetch(name) { raise ConfigurationError, "no provider for #{model.inspect}" }
|
|
64
|
+
key = api_key || ENV.fetch(API_KEY_ENV.fetch(name), nil)
|
|
65
|
+
raise ConfigurationError, "no API key for #{name}" if key.to_s.empty?
|
|
66
|
+
|
|
67
|
+
klass.new(api_key: key, model: model, **)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Build an agent for a model in one call: infers and constructs the provider,
|
|
71
|
+
# then wraps it in the loop.
|
|
72
|
+
#
|
|
73
|
+
# agent = Mistri.agent("claude-opus-4-8", tools: [weather], system: "Be brief.")
|
|
74
|
+
# agent.run("Weather in Lahore?") { |event| ... }
|
|
75
|
+
def agent(model, api_key: nil, provider_options: {}, **agent_options)
|
|
76
|
+
built = provider(model, api_key: api_key, **provider_options)
|
|
77
|
+
Agent.new(provider: built, **agent_options)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Catalogued models infer directly; unknown ids fall back to the id prefix,
|
|
81
|
+
# so a brand-new model works before it is catalogued.
|
|
82
|
+
def provider_name(model)
|
|
83
|
+
Models.find(model)&.provider || infer_provider_name(model)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def infer_provider_name(model)
|
|
87
|
+
case model.to_s
|
|
88
|
+
when /\Aclaude/ then :anthropic
|
|
89
|
+
when /\A(gpt|o\d|chatgpt)/ then :openai
|
|
90
|
+
when /\Agemini/ then :gemini
|
|
91
|
+
else raise ConfigurationError, "cannot infer a provider from #{model.inspect}"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
7
94
|
end
|
metadata
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mistri
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Muhammad Ahmed Cheema
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
|
-
description: 'Mistri (مستری) is the fixer: an agent harness
|
|
14
|
-
|
|
13
|
+
description: 'Mistri (مستری) is the fixer: an agent harness that lives inside your
|
|
14
|
+
app. Durable sessions in your own database, streaming, tools, fire-and-forget human
|
|
15
|
+
approval, steering, compaction, structured output, skills, and sub-agents, across
|
|
16
|
+
Anthropic, OpenAI, and Gemini, with zero runtime dependencies.'
|
|
15
17
|
email:
|
|
16
18
|
executables: []
|
|
17
19
|
extensions: []
|
|
@@ -21,14 +23,75 @@ files:
|
|
|
21
23
|
- LICENSE
|
|
22
24
|
- NOTICE
|
|
23
25
|
- README.md
|
|
26
|
+
- lib/generators/mistri/install/install_generator.rb
|
|
27
|
+
- lib/generators/mistri/install/templates/migration.rb.tt
|
|
28
|
+
- lib/generators/mistri/install/templates/model.rb.tt
|
|
24
29
|
- lib/mistri.rb
|
|
30
|
+
- lib/mistri/abort_signal.rb
|
|
31
|
+
- lib/mistri/agent.rb
|
|
32
|
+
- lib/mistri/budget.rb
|
|
33
|
+
- lib/mistri/compaction.rb
|
|
34
|
+
- lib/mistri/compactor.rb
|
|
35
|
+
- lib/mistri/content.rb
|
|
36
|
+
- lib/mistri/edit.rb
|
|
37
|
+
- lib/mistri/errors.rb
|
|
38
|
+
- lib/mistri/event.rb
|
|
39
|
+
- lib/mistri/memory.rb
|
|
40
|
+
- lib/mistri/message.rb
|
|
41
|
+
- lib/mistri/models.rb
|
|
42
|
+
- lib/mistri/partial_json.rb
|
|
43
|
+
- lib/mistri/providers/anthropic.rb
|
|
44
|
+
- lib/mistri/providers/anthropic/assembler.rb
|
|
45
|
+
- lib/mistri/providers/anthropic/serializer.rb
|
|
46
|
+
- lib/mistri/providers/fake.rb
|
|
47
|
+
- lib/mistri/providers/gemini.rb
|
|
48
|
+
- lib/mistri/providers/gemini/assembler.rb
|
|
49
|
+
- lib/mistri/providers/gemini/serializer.rb
|
|
50
|
+
- lib/mistri/providers/openai.rb
|
|
51
|
+
- lib/mistri/providers/openai/assembler.rb
|
|
52
|
+
- lib/mistri/providers/openai/serializer.rb
|
|
53
|
+
- lib/mistri/result.rb
|
|
54
|
+
- lib/mistri/retry_policy.rb
|
|
55
|
+
- lib/mistri/schema.rb
|
|
56
|
+
- lib/mistri/session.rb
|
|
57
|
+
- lib/mistri/sinks/action_cable.rb
|
|
58
|
+
- lib/mistri/sinks/coalesced.rb
|
|
59
|
+
- lib/mistri/sinks/sse.rb
|
|
60
|
+
- lib/mistri/skill.rb
|
|
61
|
+
- lib/mistri/skills.rb
|
|
62
|
+
- lib/mistri/sse.rb
|
|
63
|
+
- lib/mistri/stop_reason.rb
|
|
64
|
+
- lib/mistri/stores/active_record.rb
|
|
65
|
+
- lib/mistri/stores/jsonl.rb
|
|
66
|
+
- lib/mistri/stores/memory.rb
|
|
67
|
+
- lib/mistri/sub_agent.rb
|
|
68
|
+
- lib/mistri/tool.rb
|
|
69
|
+
- lib/mistri/tool_call.rb
|
|
70
|
+
- lib/mistri/tool_context.rb
|
|
71
|
+
- lib/mistri/tool_executor.rb
|
|
72
|
+
- lib/mistri/tool_result.rb
|
|
73
|
+
- lib/mistri/tools.rb
|
|
74
|
+
- lib/mistri/tools/edit_file.rb
|
|
75
|
+
- lib/mistri/tools/find_in_file.rb
|
|
76
|
+
- lib/mistri/tools/list_files.rb
|
|
77
|
+
- lib/mistri/tools/read_file.rb
|
|
78
|
+
- lib/mistri/tools/read_memory.rb
|
|
79
|
+
- lib/mistri/tools/update_memory.rb
|
|
80
|
+
- lib/mistri/tools/write_file.rb
|
|
81
|
+
- lib/mistri/transport.rb
|
|
82
|
+
- lib/mistri/usage.rb
|
|
25
83
|
- lib/mistri/version.rb
|
|
84
|
+
- lib/mistri/workspace/active_record.rb
|
|
85
|
+
- lib/mistri/workspace/directory.rb
|
|
86
|
+
- lib/mistri/workspace/memory.rb
|
|
87
|
+
- lib/mistri/workspace/single.rb
|
|
26
88
|
homepage: https://github.com/mcheemaa/mistri
|
|
27
89
|
licenses:
|
|
28
90
|
- MIT
|
|
29
91
|
metadata:
|
|
30
92
|
source_code_uri: https://github.com/mcheemaa/mistri
|
|
31
93
|
changelog_uri: https://github.com/mcheemaa/mistri/blob/main/CHANGELOG.md
|
|
94
|
+
rubygems_mfa_required: 'true'
|
|
32
95
|
post_install_message:
|
|
33
96
|
rdoc_options: []
|
|
34
97
|
require_paths:
|
|
@@ -47,5 +110,5 @@ requirements: []
|
|
|
47
110
|
rubygems_version: 3.5.22
|
|
48
111
|
signing_key:
|
|
49
112
|
specification_version: 4
|
|
50
|
-
summary:
|
|
113
|
+
summary: The agent harness for Ruby applications.
|
|
51
114
|
test_files: []
|