outcome-machine 0.0.1__tar.gz
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.
- outcome_machine-0.0.1/LICENSE +21 -0
- outcome_machine-0.0.1/MANIFEST.in +1 -0
- outcome_machine-0.0.1/PKG-INFO +54 -0
- outcome_machine-0.0.1/README.md +38 -0
- outcome_machine-0.0.1/pyproject.toml +32 -0
- outcome_machine-0.0.1/setup.cfg +4 -0
- outcome_machine-0.0.1/src/outcome_machine/__init__.py +20 -0
- outcome_machine-0.0.1/src/outcome_machine/cli.py +164 -0
- outcome_machine-0.0.1/src/outcome_machine/config.py +32 -0
- outcome_machine-0.0.1/src/outcome_machine/githf.py +69 -0
- outcome_machine-0.0.1/src/outcome_machine/machina.yaml +32 -0
- outcome_machine-0.0.1/src/outcome_machine/machine.py +238 -0
- outcome_machine-0.0.1/src/outcome_machine/providers/__init__.py +7 -0
- outcome_machine-0.0.1/src/outcome_machine/providers/basta.py +82 -0
- outcome_machine-0.0.1/src/outcome_machine/providers/castor_pollux.py +127 -0
- outcome_machine-0.0.1/src/outcome_machine/providers/depsek.py +82 -0
- outcome_machine-0.0.1/src/outcome_machine/providers/electroid.py +78 -0
- outcome_machine-0.0.1/src/outcome_machine/providers/illuminati.py +87 -0
- outcome_machine-0.0.1/src/outcome_machine/providers/metai.py +164 -0
- outcome_machine-0.0.1/src/outcome_machine/providers/openai.py +82 -0
- outcome_machine-0.0.1/src/outcome_machine/providers/qrog.py +82 -0
- outcome_machine-0.0.1/src/outcome_machine/providers/strangelove.py +81 -0
- outcome_machine-0.0.1/src/outcome_machine/providers/tinker.py +83 -0
- outcome_machine-0.0.1/src/outcome_machine/utilities.py +418 -0
- outcome_machine-0.0.1/src/outcome_machine.egg-info/PKG-INFO +54 -0
- outcome_machine-0.0.1/src/outcome_machine.egg-info/SOURCES.txt +32 -0
- outcome_machine-0.0.1/src/outcome_machine.egg-info/dependency_links.txt +1 -0
- outcome_machine-0.0.1/src/outcome_machine.egg-info/entry_points.txt +2 -0
- outcome_machine-0.0.1/src/outcome_machine.egg-info/requires.txt +1 -0
- outcome_machine-0.0.1/src/outcome_machine.egg-info/top_level.txt +1 -0
- outcome_machine-0.0.1/tests/test_cli.py +20 -0
- outcome_machine-0.0.1/tests/test_e2e.py +45 -0
- outcome_machine-0.0.1/tests/test_llm_soup.py +71 -0
- outcome_machine-0.0.1/tests/test_utilities.py +69 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Alexander Fedotov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
include src/outcome_machine/*.yaml
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: outcome-machine
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A machine that reckons
|
|
5
|
+
Author-email: Machina Ratiocinatrix <machina.ratio@gmail.com>, Alexander Fedotov <alex.fedotov@aol.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/outcome-machine/outcome-machine
|
|
7
|
+
Keywords: outcome-machine
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: pyyaml==6.0.3
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# Outcome-Machine
|
|
18
|
+
A Machine that reckons.
|
|
19
|
+
|
|
20
|
+
In order to launch it from the command line or as a Python subprocess:
|
|
21
|
+
```bash
|
|
22
|
+
echo "Theodotos-Alexandreus: What is the outcome, machine?" \
|
|
23
|
+
| uvx outcome-machine \
|
|
24
|
+
--provider-api-key sk-proj-... \
|
|
25
|
+
--github-token ghp_...
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or, with a local pip installation:
|
|
29
|
+
```bash
|
|
30
|
+
pip install outcome-machine
|
|
31
|
+
```
|
|
32
|
+
Set the environment variables:
|
|
33
|
+
```bash
|
|
34
|
+
export PROVIDER_API_KEY="sk-proj-..."
|
|
35
|
+
export GITHUB_TOKEN="ghp_..."
|
|
36
|
+
```
|
|
37
|
+
Then:
|
|
38
|
+
```bash
|
|
39
|
+
outcome-machine -a multilogue.txt
|
|
40
|
+
```
|
|
41
|
+
Or:
|
|
42
|
+
```bash
|
|
43
|
+
outcome-machine multilogue.txt > response.txt
|
|
44
|
+
```
|
|
45
|
+
Or:
|
|
46
|
+
```bash
|
|
47
|
+
outcome-machine -a multilogue.txt > tmp && echo tmp > multilogue.txt
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Or use it in your Python code:
|
|
51
|
+
```Python
|
|
52
|
+
# Python
|
|
53
|
+
import outcome_machine
|
|
54
|
+
```
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Outcome-Machine
|
|
2
|
+
A Machine that reckons.
|
|
3
|
+
|
|
4
|
+
In order to launch it from the command line or as a Python subprocess:
|
|
5
|
+
```bash
|
|
6
|
+
echo "Theodotos-Alexandreus: What is the outcome, machine?" \
|
|
7
|
+
| uvx outcome-machine \
|
|
8
|
+
--provider-api-key sk-proj-... \
|
|
9
|
+
--github-token ghp_...
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Or, with a local pip installation:
|
|
13
|
+
```bash
|
|
14
|
+
pip install outcome-machine
|
|
15
|
+
```
|
|
16
|
+
Set the environment variables:
|
|
17
|
+
```bash
|
|
18
|
+
export PROVIDER_API_KEY="sk-proj-..."
|
|
19
|
+
export GITHUB_TOKEN="ghp_..."
|
|
20
|
+
```
|
|
21
|
+
Then:
|
|
22
|
+
```bash
|
|
23
|
+
outcome-machine -a multilogue.txt
|
|
24
|
+
```
|
|
25
|
+
Or:
|
|
26
|
+
```bash
|
|
27
|
+
outcome-machine multilogue.txt > response.txt
|
|
28
|
+
```
|
|
29
|
+
Or:
|
|
30
|
+
```bash
|
|
31
|
+
outcome-machine -a multilogue.txt > tmp && echo tmp > multilogue.txt
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or use it in your Python code:
|
|
35
|
+
```Python
|
|
36
|
+
# Python
|
|
37
|
+
import outcome_machine
|
|
38
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools==82.0.1"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "outcome-machine"
|
|
7
|
+
version = "0.0.1"
|
|
8
|
+
authors = [
|
|
9
|
+
{name="Machina Ratiocinatrix", email="machina.ratio@gmail.com"},
|
|
10
|
+
{name="Alexander Fedotov", email="alex.fedotov@aol.com"}
|
|
11
|
+
]
|
|
12
|
+
description = "A machine that reckons"
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
requires-python = ">=3.10"
|
|
15
|
+
classifiers=[
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
]
|
|
20
|
+
keywords = ["outcome-machine"]
|
|
21
|
+
dependencies = [
|
|
22
|
+
"pyyaml == 6.0.3"
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.scripts]
|
|
26
|
+
outcome-machine = "outcome_machine.cli:run"
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
"Homepage" = "https://github.com/outcome-machine/outcome-machine"
|
|
30
|
+
|
|
31
|
+
[dependency-groups]
|
|
32
|
+
dev = ["pytest>=8.0.0"]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Python
|
|
3
|
+
|
|
4
|
+
"""Copyright (c) Alexander Fedotov.
|
|
5
|
+
This source code is licensed under the license found in the
|
|
6
|
+
LICENSE file in the root directory of this source tree.
|
|
7
|
+
"""
|
|
8
|
+
from .config import Config
|
|
9
|
+
from .machine import machine
|
|
10
|
+
from .githf import fetch_instructions
|
|
11
|
+
from .utilities import (plato_text_to_muj,
|
|
12
|
+
plato_text_to_mpuj,
|
|
13
|
+
llm_soup_to_text,
|
|
14
|
+
new_plato_text)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
'machine',
|
|
18
|
+
'fetch_instructions',
|
|
19
|
+
'Config'
|
|
20
|
+
]
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Python
|
|
3
|
+
|
|
4
|
+
"""Copyright (c) Alexander Fedotov.
|
|
5
|
+
This source code is licensed under the license found in the
|
|
6
|
+
LICENSE file in the root directory of this source tree.
|
|
7
|
+
"""
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
import select
|
|
11
|
+
import fileinput
|
|
12
|
+
import argparse
|
|
13
|
+
import syslog
|
|
14
|
+
from .config import Config
|
|
15
|
+
from .utilities import new_plato_text
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def options_and_arguments():
|
|
19
|
+
# Initialize the parser
|
|
20
|
+
parser = argparse.ArgumentParser(
|
|
21
|
+
description="Outcome-Machine thinks for you about the meanings.",
|
|
22
|
+
epilog="Example: outcome-machine input_text.txt > output_text.txt"
|
|
23
|
+
# thinking-machine -a multilogue.txt > tmp && mv tmp multilogue.txt
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
# Give the access key and token, or set the environment variables in advance.
|
|
27
|
+
parser.add_argument('-p', '--provider-api-key',
|
|
28
|
+
default=os.getenv('PROVIDER_API_KEY', 'no_key'),
|
|
29
|
+
help="LLM provider API key (defaults to $PROVIDER_API_KEY)")
|
|
30
|
+
parser.add_argument('-g', '--github-token',
|
|
31
|
+
default=os.getenv('GITHUB_TOKEN', 'no_token'),
|
|
32
|
+
help="GitHub API token (defaults to $GITHUB_TOKEN)")
|
|
33
|
+
|
|
34
|
+
parser.add_argument('-a', '--append',
|
|
35
|
+
action='store_true',
|
|
36
|
+
help="Append the utterance to the input.")
|
|
37
|
+
|
|
38
|
+
parser.add_argument('-d', '--debug',
|
|
39
|
+
action='store_true',
|
|
40
|
+
help="Debug flag.")
|
|
41
|
+
|
|
42
|
+
# Add the interactive flag
|
|
43
|
+
# parser.add_argument('-i', '--interactive',
|
|
44
|
+
# action='store_true',
|
|
45
|
+
# help="Enable interactive mode (defaults to False)")
|
|
46
|
+
|
|
47
|
+
# Positional arguments (files)
|
|
48
|
+
# '*' captures zero or more arguments into a list, nargs='+' one or more.
|
|
49
|
+
parser.add_argument('filenames',
|
|
50
|
+
nargs='*',
|
|
51
|
+
help="Zero (when text comes though a pipe) or more files to process.")
|
|
52
|
+
return parser
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def run():
|
|
56
|
+
"""
|
|
57
|
+
$ text | outcome-machine # Accepts text from the pipe
|
|
58
|
+
$ echo "...<text>..." | outcome-machine #
|
|
59
|
+
|
|
60
|
+
$ outcome-machine multilogue.txt new_turn.txt # ...or files.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
args = options_and_arguments().parse_args()
|
|
64
|
+
|
|
65
|
+
# If no files are provided AND no data is being piped in - exit.
|
|
66
|
+
if not args.filenames:
|
|
67
|
+
# Check if stdin (fd 0) is ready to be read
|
|
68
|
+
readable, _, _ = select.select([sys.stdin], [], [], 0.1)
|
|
69
|
+
if not readable:
|
|
70
|
+
print("Error: No input files or piped text stream.")
|
|
71
|
+
options_and_arguments().print_help()
|
|
72
|
+
sys.exit(1)
|
|
73
|
+
|
|
74
|
+
config = Config()
|
|
75
|
+
|
|
76
|
+
if args.provider_api_key:
|
|
77
|
+
if args.provider_api_key.startswith('sk-'):
|
|
78
|
+
if args.provider_api_key.startswith('sk-proj-'):
|
|
79
|
+
config.provider = 'OpenAI'
|
|
80
|
+
os.environ['OPENAI_API_KEY'] = args.provider_api_key
|
|
81
|
+
elif args.provider_api_key.startswith('sk-ant-'):
|
|
82
|
+
config.provider = 'Anthropic'
|
|
83
|
+
os.environ['ANTHROPIC_API_KEY'] = args.provider_api_key
|
|
84
|
+
else:
|
|
85
|
+
config.provider = 'DepSek'
|
|
86
|
+
os.environ['DEPSEK_API_KEY'] = args.provider_api_key
|
|
87
|
+
elif args.provider_api_key.startswith('AIzaSy'):
|
|
88
|
+
config.provider = 'Gemini'
|
|
89
|
+
os.environ['GEMINI_API_KEY'] = args.provider_api_key
|
|
90
|
+
elif args.provider_api_key.startswith('gsk_'):
|
|
91
|
+
config.provider = 'Groq'
|
|
92
|
+
os.environ['GROQ_API_KEY'] = args.provider_api_key
|
|
93
|
+
elif args.provider_api_key.startswith('xai-'):
|
|
94
|
+
config.provider = 'XAI'
|
|
95
|
+
os.environ['XAI_API_KEY'] = args.provider_api_key
|
|
96
|
+
elif args.provider_api_key.startswith('LLM'):
|
|
97
|
+
config.provider = 'MetAI'
|
|
98
|
+
os.environ['METAI_API_KEY'] = args.provider_api_key
|
|
99
|
+
elif args.provider_api_key.startswith('tml-'):
|
|
100
|
+
config.provider = 'Tinker'
|
|
101
|
+
os.environ['TINKER_API_KEY'] = args.provider_api_key
|
|
102
|
+
elif args.provider_api_key == 'no_provider_key':
|
|
103
|
+
sys.stderr.write(f'No provider key!\n')
|
|
104
|
+
sys.stderr.flush()
|
|
105
|
+
sys.exit(1)
|
|
106
|
+
else:
|
|
107
|
+
if config.provider == '':
|
|
108
|
+
raise ValueError(f"Unrecognized API key prefix and no provider specified.")
|
|
109
|
+
else:
|
|
110
|
+
if config.provider == 'Baseten':
|
|
111
|
+
os.environ['BASETEN_API_KEY'] = args.provider_api_key
|
|
112
|
+
elif config.provider == 'Fireworks':
|
|
113
|
+
os.environ['FIREWORKS_API_KEY'] = args.provider_api_key
|
|
114
|
+
elif config.provider == 'Lightning':
|
|
115
|
+
os.environ['LIGHTNING_API_KEY'] = args.provider_api_key
|
|
116
|
+
else:
|
|
117
|
+
raise ValueError(f"Unsupported provider specified.")
|
|
118
|
+
|
|
119
|
+
config.provider_api_key = args.provider_api_key
|
|
120
|
+
|
|
121
|
+
if args.github_token:
|
|
122
|
+
config.github_token = args.github_token
|
|
123
|
+
os.environ['GITHUB_TOKEN'] = args.github_token
|
|
124
|
+
|
|
125
|
+
# Ingest files line by line. Join is here for long files.
|
|
126
|
+
lines = []
|
|
127
|
+
for line in fileinput.input(files=args.filenames or ['-'], encoding="utf-8"):
|
|
128
|
+
lines.append(line)
|
|
129
|
+
raw_input = "".join(lines)
|
|
130
|
+
|
|
131
|
+
from .machine import machine
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
thoughts, text = machine(raw_input, config)
|
|
135
|
+
output = new_plato_text(thoughts, text, config.name)
|
|
136
|
+
if args.append:
|
|
137
|
+
output = raw_input +'\n\n' + output
|
|
138
|
+
sys.stdout.write(output)
|
|
139
|
+
sys.stdout.flush()
|
|
140
|
+
|
|
141
|
+
# Assesment and signals.
|
|
142
|
+
utterance = "My answer is ready"
|
|
143
|
+
# Open syslog connection
|
|
144
|
+
syslog.openlog(
|
|
145
|
+
ident="outcome-machine",
|
|
146
|
+
logoption=syslog.LOG_NDELAY,
|
|
147
|
+
facility=syslog.LOG_USER
|
|
148
|
+
)
|
|
149
|
+
# Signal (single line less than 4096 only!)
|
|
150
|
+
syslog.syslog(syslog.LOG_INFO, f"outcome-machine: {utterance}.")
|
|
151
|
+
syslog.closelog()
|
|
152
|
+
|
|
153
|
+
except Exception as e:
|
|
154
|
+
if args.debug:
|
|
155
|
+
import traceback
|
|
156
|
+
traceback.print_exc()
|
|
157
|
+
else:
|
|
158
|
+
sys.stderr.write(f'Machine did not work {e}\n')
|
|
159
|
+
sys.stderr.flush()
|
|
160
|
+
sys.exit(1)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
if __name__ == '__main__':
|
|
164
|
+
run()
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Python
|
|
3
|
+
|
|
4
|
+
"""Copyright (c) Alexander Fedotov.
|
|
5
|
+
This source code is licensed under the license found in the
|
|
6
|
+
LICENSE file in the root directory of this source tree.
|
|
7
|
+
"""
|
|
8
|
+
from os import environ
|
|
9
|
+
from dataclasses import dataclass, field, asdict
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class Config:
|
|
14
|
+
github_token: str = field(default_factory=lambda: environ.get('GITHUB_TOKEN', ''))
|
|
15
|
+
github_name: str = field(default_factory=lambda: environ.get('GITHUB_NAME', ''))
|
|
16
|
+
github_email: str = field(default_factory=lambda: environ.get('GITHUB_EMAIL', ''))
|
|
17
|
+
provider_api_key: str = field(default_factory=lambda: environ.get('PROVIDER_API_KEY', ''))
|
|
18
|
+
provider: str = field(default_factory=lambda: environ.get('PROVIDER', ''))
|
|
19
|
+
machine_organization_name: str = field(default_factory=lambda: environ.get('MACHINE_ORGANIZATION_NAME', 'outcome-machine'))
|
|
20
|
+
private_repo_with_text: str = field(default_factory=lambda: environ.get('PRIVATE_REPO_WITH_TEXT','outcome_machine'))
|
|
21
|
+
system_prompt_file: str = field(default_factory=lambda: environ.get('SYSTEM_PROMPT_FILE', 'machina.yaml'))
|
|
22
|
+
name: str = ''
|
|
23
|
+
instructions: str = ''
|
|
24
|
+
verb: str = ''
|
|
25
|
+
|
|
26
|
+
def to_dict(self):
|
|
27
|
+
return asdict(self)
|
|
28
|
+
|
|
29
|
+
def update_from_dict(self, data: dict):
|
|
30
|
+
for key, value in data.items():
|
|
31
|
+
if hasattr(self, key):
|
|
32
|
+
setattr(self, key, value)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Python
|
|
3
|
+
|
|
4
|
+
"""Copyright (c) Alexander Fedotov.
|
|
5
|
+
This source code is licensed under the license found in the
|
|
6
|
+
LICENSE file in the root directory of this source tree.
|
|
7
|
+
"""
|
|
8
|
+
import sys
|
|
9
|
+
from os import path
|
|
10
|
+
import yaml
|
|
11
|
+
import urllib.request
|
|
12
|
+
import urllib.error
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def download_github_file(owner, repo, file_path, token):
|
|
16
|
+
"""
|
|
17
|
+
Downloads a file from a GitHub repository using the GitHub REST API.
|
|
18
|
+
We request the raw content by using the 'application/vnd.github.v3.raw' accept header.
|
|
19
|
+
"""
|
|
20
|
+
url = f"https://api.github.com/repos/{owner}/{repo}/contents/{file_path}"
|
|
21
|
+
|
|
22
|
+
headers = {
|
|
23
|
+
"Authorization": f"token {token}",
|
|
24
|
+
"Accept": "application/vnd.github.v3.raw",
|
|
25
|
+
"User-Agent": "Outcome-Machine"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
req = urllib.request.Request(url, headers=headers)
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
with urllib.request.urlopen(req, timeout=10) as response:
|
|
32
|
+
return response.read()
|
|
33
|
+
except urllib.error.HTTPError as e:
|
|
34
|
+
print(f"HTTP Error {e.code}: {e.reason}")
|
|
35
|
+
error_info = e.read().decode('utf-8')
|
|
36
|
+
print(f"Details: {error_info}")
|
|
37
|
+
return None
|
|
38
|
+
except urllib.error.URLError as e:
|
|
39
|
+
print(f"URL Error: {e.reason}")
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def fetch_instructions(config):
|
|
44
|
+
"""Retrieve the system prompt from a private GitHub repo.
|
|
45
|
+
Falls back to the local machina.yaml if GitHub is unreachable.
|
|
46
|
+
Returns the 'name' of the Machine in dashed format.
|
|
47
|
+
Returns the 'description' field from the YAML as the system prompt string.
|
|
48
|
+
"""
|
|
49
|
+
try:
|
|
50
|
+
raw_yaml = download_github_file(
|
|
51
|
+
owner=config.machine_organization_name,
|
|
52
|
+
repo=config.private_repo_with_text,
|
|
53
|
+
file_path=config.system_prompt_file,
|
|
54
|
+
token=config.github_token
|
|
55
|
+
)
|
|
56
|
+
except Exception as e:
|
|
57
|
+
print(f"Warning: could not fetch the instructions from GitHub: {e}",
|
|
58
|
+
file=sys.stderr)
|
|
59
|
+
local_path = path.join(path.dirname(__file__), 'machina.yaml')
|
|
60
|
+
with open(local_path, 'r') as f:
|
|
61
|
+
raw_yaml = f.read()
|
|
62
|
+
|
|
63
|
+
# Parse
|
|
64
|
+
parsed = yaml.safe_load(raw_yaml)
|
|
65
|
+
name = parsed.get('name')
|
|
66
|
+
config.name = name
|
|
67
|
+
instructions = parsed.get('description', 'You are a helpful assistant.')
|
|
68
|
+
config.instructions = instructions
|
|
69
|
+
return name, instructions
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Copyright (c) Alexander Fedotov, 2026. All rights reserved.
|
|
2
|
+
name: Outcome-Machine
|
|
3
|
+
verb: reckon
|
|
4
|
+
description: >-
|
|
5
|
+
You are Outcome-Machine, a language model acting as an
|
|
6
|
+
active participant in multi-entity, multi-turn conversations.
|
|
7
|
+
The user relays the utterances of the other participants —
|
|
8
|
+
human and machine, addressed to you or to each other — and
|
|
9
|
+
all of it is your context.
|
|
10
|
+
|
|
11
|
+
Speak when addressed directly, and also unprompted whenever
|
|
12
|
+
you judge question or comment necessary, naming any
|
|
13
|
+
participant you address. Never introduce yourself or add
|
|
14
|
+
meta-commentary about your functioning.
|
|
15
|
+
|
|
16
|
+
Your purpose is to reckon. Fulfill this purpose
|
|
17
|
+
by grounding your work in the conversational context,
|
|
18
|
+
analyzing dynamics, unstated premises, and logical
|
|
19
|
+
structures across all utterances. Prepare and refine your
|
|
20
|
+
response before speaking.
|
|
21
|
+
|
|
22
|
+
Keep your tone strictly neutral and objective, without
|
|
23
|
+
simulated emotion. This neutrality concerns judgment, not
|
|
24
|
+
voice; write naturally.
|
|
25
|
+
|
|
26
|
+
Text formatting: Outcome-Machine responds in plain text
|
|
27
|
+
without any markdown, emphasis or lists; all paragraphs except
|
|
28
|
+
the first one should begin with a newline and a tab.
|
|
29
|
+
rubrics: |
|
|
30
|
+
Text formatting: Outcome-Machine responds in plain text
|
|
31
|
+
without any markdown, emphasis or lists; all paragraphs except
|
|
32
|
+
the first one should begin with a newline and a tab.
|