flock-core 0.2.4__py3-none-any.whl → 0.2.6__py3-none-any.whl

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.

Potentially problematic release.


This version of flock-core might be problematic. Click here for more details.

@@ -0,0 +1,49 @@
1
+ import subprocess
2
+ import time
3
+
4
+
5
+ def _check_docker_running():
6
+ """Check if Docker is running by calling 'docker info'."""
7
+ try:
8
+ result = subprocess.run(
9
+ ["docker", "info"],
10
+ stdout=subprocess.PIPE,
11
+ stderr=subprocess.PIPE,
12
+ text=True,
13
+ )
14
+ return result.returncode == 0
15
+ except Exception:
16
+ return False
17
+
18
+
19
+ def _start_docker():
20
+ """Attempt to start Docker.
21
+ This example first tries 'systemctl start docker' and then 'service docker start'.
22
+ Adjust as needed for your environment.
23
+ """
24
+ try:
25
+ print("Attempting to start Docker...")
26
+ result = subprocess.run(
27
+ ["sudo", "systemctl", "start", "docker"],
28
+ stdout=subprocess.PIPE,
29
+ stderr=subprocess.PIPE,
30
+ text=True,
31
+ )
32
+ if result.returncode != 0:
33
+ result = subprocess.run(
34
+ ["sudo", "service", "docker", "start"],
35
+ stdout=subprocess.PIPE,
36
+ stderr=subprocess.PIPE,
37
+ text=True,
38
+ )
39
+ # Give Docker a moment to start.
40
+ time.sleep(3)
41
+ if _check_docker_running():
42
+ print("Docker is now running.")
43
+ return True
44
+ else:
45
+ print("Docker did not start successfully.")
46
+ return False
47
+ except Exception as e:
48
+ print(f"Exception when trying to start Docker: {e}")
49
+ return False
@@ -0,0 +1,86 @@
1
+ import socket
2
+ import subprocess
3
+ from urllib.parse import urlparse
4
+
5
+
6
+ class JaegerInstaller:
7
+ jaeger_endpoint: str = None
8
+ jaeger_transport: str = "grpc"
9
+
10
+ def _check_jaeger_running(self):
11
+ """Check if Jaeger is reachable by attempting a socket connection.
12
+ For HTTP transport, we parse the URL; for gRPC, we expect "host:port".
13
+ """
14
+ try:
15
+ if self.jaeger_transport == "grpc":
16
+ host, port = self.jaeger_endpoint.split(":")
17
+ port = int(port)
18
+ elif self.jaeger_transport == "http":
19
+ parsed = urlparse(self.jaeger_endpoint)
20
+ host = parsed.hostname
21
+ port = parsed.port if parsed.port else 80
22
+ else:
23
+ return False
24
+
25
+ # Try connecting to the host and port.
26
+ with socket.create_connection((host, port), timeout=3):
27
+ return True
28
+ except Exception:
29
+ return False
30
+
31
+ def _is_jaeger_container_running(self):
32
+ """Check if a Jaeger container (using the official all-in-one image) is running.
33
+ This uses 'docker ps' to filter for containers running the Jaeger image.
34
+ """
35
+ try:
36
+ result = subprocess.run(
37
+ [
38
+ "docker",
39
+ "ps",
40
+ "--filter",
41
+ "ancestor=jaegertracing/all-in-one:latest",
42
+ "--format",
43
+ "{{.ID}}",
44
+ ],
45
+ stdout=subprocess.PIPE,
46
+ stderr=subprocess.PIPE,
47
+ text=True,
48
+ )
49
+ return bool(result.stdout.strip())
50
+ except Exception:
51
+ return False
52
+
53
+ def _provision_jaeger_container(self):
54
+ """Provision a Jaeger container using Docker."""
55
+ try:
56
+ print("Provisioning Jaeger container using Docker...")
57
+ result = subprocess.run(
58
+ [
59
+ "docker",
60
+ "run",
61
+ "-d",
62
+ "--name",
63
+ "jaeger",
64
+ "-p",
65
+ "16686:16686",
66
+ "-p",
67
+ "14250:14250",
68
+ "-p",
69
+ "14268:14268",
70
+ "jaegertracing/all-in-one:latest",
71
+ ],
72
+ stdout=subprocess.PIPE,
73
+ stderr=subprocess.PIPE,
74
+ text=True,
75
+ )
76
+ if result.returncode == 0:
77
+ print("Jaeger container started successfully.")
78
+ return True
79
+ else:
80
+ print(
81
+ f"Failed to start Jaeger container. Error: {result.stderr}"
82
+ )
83
+ return False
84
+ except Exception as e:
85
+ print(f"Exception when provisioning Jaeger container: {e}")
86
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flock-core
3
- Version: 0.2.4
3
+ Version: 0.2.6
4
4
  Summary: Declarative LLM Orchestration at Scale
5
5
  Author-email: Andre Ratzenberger <andre.ratzenberger@whiteduck.de>
6
6
  License-File: LICENSE
@@ -11,6 +11,7 @@ Requires-Python: >=3.10
11
11
  Requires-Dist: cloudpickle>=3.1.1
12
12
  Requires-Dist: devtools>=0.12.2
13
13
  Requires-Dist: dspy==2.5.42
14
+ Requires-Dist: duckduckgo-search>=7.3.2
14
15
  Requires-Dist: httpx>=0.28.1
15
16
  Requires-Dist: loguru>=0.7.3
16
17
  Requires-Dist: msgpack>=1.1.0
@@ -22,6 +23,7 @@ Requires-Dist: opentelemetry-instrumentation-logging>=0.51b0
22
23
  Requires-Dist: opentelemetry-sdk>=1.30.0
23
24
  Requires-Dist: pydantic>=2.10.5
24
25
  Requires-Dist: python-box>=7.3.2
26
+ Requires-Dist: python-decouple>=3.8
25
27
  Requires-Dist: rich>=13.9.4
26
28
  Requires-Dist: temporalio>=1.9.0
27
29
  Requires-Dist: toml>=0.10.2
@@ -36,7 +38,9 @@ Description-Content-Type: text/markdown
36
38
 
37
39
  <p align="center">
38
40
  <img src="docs/img/flock.png" width="600"><br>
39
- <img alt="Dynamic TOML Badge" src="https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2Fwhiteducksoftware%2Fflock%2Frefs%2Fheads%2Fbadges%2Fpyproject.toml%3Ftoken%3DGHSAT0AAAAAACVFDVNBU3S6HLJSC36P3YNQZ5LNPQQ&query=%24.project.version&style=for-the-badge&logo=pypi&logoSize=large&label=pip%20version&link=https%3A%2F%2Fpypi.org%2Fproject%2Fflock-core%2F">
41
+ <img alt="Dynamic TOML Badge" src="https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2Fwhiteducksoftware%2Fflock%2Frefs%2Fheads%2Fmaster%2Fpyproject.toml&query=%24.project.version&style=for-the-badge&logo=pypi&label=pip%20version">
42
+ <img alt="X (formerly Twitter) Follow" src="https://img.shields.io/twitter/follow/whiteduck_gmbh?style=for-the-badge&logo=X">
43
+
40
44
 
41
45
 
42
46
 
@@ -1,33 +1,38 @@
1
- flock/__init__.py,sha256=uJxXAxt0def69cccAAdLjBxQOFXVRO72RE82hJnODSw,108
2
- flock/config.py,sha256=hul_Vmgl8w5a_4YNfg3Mvll3iVEkjiR5At9D0WsVesw,1006
1
+ flock/__init__.py,sha256=P175tsTOByIhw_CIeMAybUEggKhtoSrc8a0gKotBJfo,177
2
+ flock/config.py,sha256=jmW1PQ2oiCUpERLhNFzvrcHlYS3KM_jJyMXrnoeA0gs,1547
3
3
  flock/core/__init__.py,sha256=0Xq_txurlxxjKGXjRn6GNJusGTiBcd7zw2eF0L7JyuU,183
4
- flock/core/flock.py,sha256=Iw7Frmz2aZheApxi2KSjsX7gA8ZcemzXhfKXeQdtY0w,9438
5
- flock/core/flock_agent.py,sha256=59qQ7ohOy2lc1KjI6SV7IcrqYL86ofAhq32pZGgk6eA,27761
4
+ flock/core/flock.py,sha256=0NC-J_ZCojwWDepI6rbX-9jG_Hr2AKgY43ieijhD8DU,9820
5
+ flock/core/flock_agent.py,sha256=prA2jslYuAABzIG6uw55f0XCNR-V4Ptaaju93ZuCc6E,27767
6
6
  flock/core/context/context.py,sha256=jH06w4C_O5CEL-YxjX_x_dmgLe9Rcllnn1Ebs0dvwaE,6171
7
7
  flock/core/context/context_manager.py,sha256=qMySVny_dbTNLh21RHK_YT0mNKIOrqJDZpi9ZVdBsxU,1103
8
8
  flock/core/context/context_vars.py,sha256=0Hn6fM2iNc0_jIIU0B7KX-K2o8qXqtZ5EYtwujETQ7U,272
9
9
  flock/core/execution/local_executor.py,sha256=O_dgQ_HJPCp97ghdEoDSNDIiaYkogrUS0G2FfK04RRc,973
10
10
  flock/core/execution/temporal_executor.py,sha256=ai6ikr9rEiN2Kc-208OalxtfqL_FTt_UaH6a--oEkJM,2010
11
11
  flock/core/logging/__init__.py,sha256=Q8hp9-1ilPIUIV0jLgJ3_cP7COrea32cVwL7dicPnlM,82
12
- flock/core/logging/logging.py,sha256=F-FDz9etBXmAIT-fjx3pUfvNXsckgR6ONCMaFZIc4Kw,4619
13
- flock/core/logging/telemetry.py,sha256=T2CRSiqOWvOsXe-WRsObkkOkrrd6z-BwEYLaBUU2AAM,4017
14
- flock/core/logging/trace_and_logged.py,sha256=h4YH8s0KjK4tiBdrEZdCLd4fDzMB5-NKwqzrtkWhQw4,1999
12
+ flock/core/logging/logging.py,sha256=dOo_McbAt9_dST9Hr8RTpAGU-MHR_QvskIdmXrSvZRc,4789
13
+ flock/core/logging/telemetry.py,sha256=yEOfEZ3HBFeLCaHZA6QmsRdwZKtmUC6bQtEOTVeRR4o,5314
14
+ flock/core/logging/trace_and_logged.py,sha256=5vNrK1kxuPMoPJ0-QjQg-EDJL1oiEzvU6UNi6X8FiMs,2117
15
15
  flock/core/logging/formatters/base_formatter.py,sha256=CyG-X2NWq8sqEhFEO2aG7Mey5tVkIzoWiihW301_VIo,1023
16
16
  flock/core/logging/formatters/formatter_factory.py,sha256=hmH-NpCESHkioX0GBQ5CuQR4axyIXnSRWwAZCHylx6Q,1283
17
- flock/core/logging/formatters/pprint_formatter.py,sha256=tTm2WhwlCw-SX2Ouci5I9U_HVgxNGY5SSnzB9HZh8bg,692
17
+ flock/core/logging/formatters/pprint_formatter.py,sha256=cONC9hS-QFXqj9iStVpLwsoNG8asVcc8tduTRRhGQ5o,742
18
18
  flock/core/logging/formatters/rich_formatters.py,sha256=h1FD0_cIdQBQ8P2x05XhgD1cmmP80IBNVT5jb3cAV9M,4776
19
19
  flock/core/logging/formatters/theme_builder.py,sha256=1RUEwPIDfCjwTapbK1liasA5SdukOn7YwbZ4H4j1WkI,17364
20
20
  flock/core/logging/formatters/themed_formatter.py,sha256=CbxmqUC7zkLzyIxngk-3dcpQ6vxPR6zaDNA2TAMitCI,16714
21
- flock/core/logging/telemetry_exporter/file_span.py,sha256=e4hr4D7tC9j4KT7JZBuZU0YxQCdHKADpXNeUNEwggN4,1294
22
- flock/core/logging/telemetry_exporter/sqllite_span.py,sha256=9bqxHt1mDQGyhKxA9dON5xDi_6FMOfBSdrU_zWV0xv4,2107
23
- flock/core/mixin/dspy_integration.py,sha256=oT5YfXxPhHkMCuwhXoppBAYBGePUAKse7KebGSM-bq0,6880
21
+ flock/core/logging/span_middleware/baggage_span_processor.py,sha256=gJfRl8FeB6jdtghTaRHCrOaTo4fhPMRKgjqtZj-8T48,1118
22
+ flock/core/logging/telemetry_exporter/base_exporter.py,sha256=rQJJzS6q9n2aojoSqwCnl7ZtHrh5LZZ-gkxUuI5WfrQ,1124
23
+ flock/core/logging/telemetry_exporter/file_exporter.py,sha256=nKAjJSZtA7FqHSTuTiFtYYepaxOq7l1rDvs8U8rSBlA,3023
24
+ flock/core/logging/telemetry_exporter/sqlite_exporter.py,sha256=CDsiMb9QcqeXelZ6ZqPSS56ovMPGqOu6whzBZRK__Vg,3498
25
+ flock/core/mixin/dspy_integration.py,sha256=eFCe6B8vMmgKXY0eFIN_x_5DYyt0AZsffYXPSHTsO0U,7379
24
26
  flock/core/mixin/prompt_parser.py,sha256=eOqI-FK3y17gVqpc_y5GF-WmK1Jv8mFlkZxTcgweoxI,5121
25
27
  flock/core/registry/agent_registry.py,sha256=QHdr3Cb-32PEdz8jFCIZSH9OlfpRwAJMtSRpHCWJDq4,4889
26
- flock/core/tools/basic_tools.py,sha256=nRc1bIz96z-WUTe_yYf9V6EfCPEncl_XnrpGdC7dEmo,8721
27
- flock/core/tools/dev_tools/github.py,sha256=6ya2_eN-qITV3b_pYP24jQC3X4oZbRY5GKh1AF-9Zic,6836
28
+ flock/core/tools/basic_tools.py,sha256=OwWaFu4NoVrc3Uijj56RY9XDDaP_mOnEa5B3wSWwwLE,4756
29
+ flock/core/tools/dev_tools/github.py,sha256=a2OTPXS7kWOVA4zrZHynQDcsmEi4Pac5MfSjQOLePzA,5308
28
30
  flock/core/util/cli_helper.py,sha256=aHLKjl5JBLIczLzjYeUcGQlVQRlypunxV2TYeAFX0KE,1030
29
- flock/core/util/input_resolver.py,sha256=OesGqX2Dld8myL9Qz04mmxLqoYqOSQC632pj1EMk9Yk,5456
31
+ flock/core/util/input_resolver.py,sha256=g9vDPdY4OH-G7qjas5ksGEHueokHGFPMoLOvC-ngeLo,5984
30
32
  flock/core/util/serializable.py,sha256=SymJ0YrjBx48mOBItYSqoRpKuzIc4vKWRS6ScTzre7s,2573
33
+ flock/interpreter/python_interpreter.py,sha256=pq2e7KJfAYtBCP2hhbtFNeg18QdMFF66esoYn3MHfA4,26177
34
+ flock/platform/docker_tools.py,sha256=fpA7-6rJBjPOUBLdQP4ny2QPgJ_042nmqRn5GtKnoYw,1445
35
+ flock/platform/jaeger_install.py,sha256=MyOMJQx4TQSMYvdUJxfiGSo3YCtsfkbNXcAcQ9bjETA,2898
31
36
  flock/themes/3024-day.toml,sha256=uOVHqEzSyHx0WlUk3D0lne4RBsNBAPCTy3C58yU7kEY,667
32
37
  flock/themes/3024-night.toml,sha256=qsXUwd6ZYz6J-R129_Ao2TKlvvK60svhZJJjB5c8Tfo,1667
33
38
  flock/themes/aardvark-blue.toml,sha256=Px1qevE6J1ZAc_jAqF_FX674KdIv_3pAYNKmmvDxIbE,1672
@@ -369,7 +374,8 @@ flock/workflow/activities.py,sha256=YEg-Gr8kzVsxWsmsZguIVhX2XwMRvhZ2OlnsJoG5g_A,
369
374
  flock/workflow/agent_activities.py,sha256=NhBZscflEf2IMfSRa_pBM_TRP7uVEF_O0ROvWZ33eDc,963
370
375
  flock/workflow/temporal_setup.py,sha256=VWBgmBgfTBjwM5ruS_dVpA5AVxx6EZ7oFPGw4j3m0l0,1091
371
376
  flock/workflow/workflow.py,sha256=I9MryXW_bqYVTHx-nl2epbTqeRy27CAWHHA7ZZA0nAk,1696
372
- flock_core-0.2.4.dist-info/METADATA,sha256=VztTdTQKj4pIiPnSearGjlMDmPA_1o0Nak_EefDzs4o,11488
373
- flock_core-0.2.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
374
- flock_core-0.2.4.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
375
- flock_core-0.2.4.dist-info/RECORD,,
377
+ flock_core-0.2.6.dist-info/METADATA,sha256=5N_MIPv2rCJtiGwp3jYf-Bz8EWfj8h-B_mK-jPsCsT0,11569
378
+ flock_core-0.2.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
379
+ flock_core-0.2.6.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
380
+ flock_core-0.2.6.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
381
+ flock_core-0.2.6.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ flock = flock:main
@@ -1,37 +0,0 @@
1
- import json
2
-
3
- from opentelemetry.sdk.trace.export import (
4
- SpanExporter,
5
- SpanExportResult,
6
- )
7
-
8
-
9
- class FileSpanExporter(SpanExporter):
10
- """A simple exporter that writes span data as JSON lines into a file."""
11
-
12
- def __init__(self, file_path: str):
13
- self.file_path = file_path
14
-
15
- def export(self, spans) -> SpanExportResult:
16
- try:
17
- with open(self.file_path, "a") as f:
18
- for span in spans:
19
- # Create a dictionary representation of the span.
20
- span_dict = {
21
- "name": span.name,
22
- "trace_id": format(span.context.trace_id, "032x"),
23
- "span_id": format(span.context.span_id, "016x"),
24
- "start_time": span.start_time,
25
- "end_time": span.end_time,
26
- "attributes": span.attributes,
27
- "status": str(span.status),
28
- }
29
- f.write(json.dumps(span_dict) + "\n")
30
- return SpanExportResult.SUCCESS
31
- except Exception as e:
32
- print("Error exporting spans to file:", e)
33
- return SpanExportResult.FAILURE
34
-
35
- def shutdown(self) -> None:
36
- # Nothing special needed on shutdown.
37
- pass
@@ -1,68 +0,0 @@
1
- import json
2
- import sqlite3
3
-
4
- from opentelemetry.sdk.trace.export import (
5
- SpanExporter,
6
- SpanExportResult,
7
- )
8
-
9
-
10
- class SQLiteSpanExporter(SpanExporter):
11
- """A custom exporter that writes span data into a SQLite database."""
12
-
13
- def __init__(self, sqlite_db_path: str):
14
- self.sqlite_db_path = sqlite_db_path
15
- self.conn = sqlite3.connect(
16
- self.sqlite_db_path, check_same_thread=False
17
- )
18
- self._create_table()
19
-
20
- def _create_table(self):
21
- cursor = self.conn.cursor()
22
- cursor.execute(
23
- """
24
- CREATE TABLE IF NOT EXISTS spans (
25
- id TEXT PRIMARY KEY,
26
- name TEXT,
27
- trace_id TEXT,
28
- span_id TEXT,
29
- start_time INTEGER,
30
- end_time INTEGER,
31
- attributes TEXT,
32
- status TEXT
33
- )
34
- """
35
- )
36
- self.conn.commit()
37
-
38
- def export(self, spans) -> SpanExportResult:
39
- try:
40
- cursor = self.conn.cursor()
41
- for span in spans:
42
- span_id = format(span.context.span_id, "016x")
43
- trace_id = format(span.context.trace_id, "032x")
44
- cursor.execute(
45
- """
46
- INSERT OR REPLACE INTO spans
47
- (id, name, trace_id, span_id, start_time, end_time, attributes, status)
48
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
49
- """,
50
- (
51
- span_id,
52
- span.name,
53
- trace_id,
54
- span_id,
55
- span.start_time,
56
- span.end_time,
57
- json.dumps(span.attributes),
58
- str(span.status),
59
- ),
60
- )
61
- self.conn.commit()
62
- return SpanExportResult.SUCCESS
63
- except Exception as e:
64
- print("Error exporting spans to SQLite:", e)
65
- return SpanExportResult.FAILURE
66
-
67
- def shutdown(self) -> None:
68
- self.conn.close()