nextloop 0.1.0rc1__tar.gz → 0.1.0rc2__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.
- {nextloop-0.1.0rc1/src/nextloop.egg-info → nextloop-0.1.0rc2}/PKG-INFO +5 -4
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/README.md +4 -3
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/pyproject.toml +1 -1
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/adapters/memory.py +6 -1
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/adapters/sqlite.py +1 -1
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/events/project.py +18 -1
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2/src/nextloop.egg-info}/PKG-INFO +5 -4
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/tests/test_loop.py +3 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/LICENSE +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/setup.cfg +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/__init__.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/adapters/__init__.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/adapters/_sse.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/adapters/anthropic.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/adapters/openai.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/contracts.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/driver.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/events/__init__.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/events/outcome.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/events/repair.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/events/response.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/execute/__init__.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/execute/batch.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/execute/model.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/execute/tools.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/loop.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop/py.typed +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop.egg-info/SOURCES.txt +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop.egg-info/dependency_links.txt +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop.egg-info/requires.txt +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/src/nextloop.egg-info/top_level.txt +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/tests/test_events.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/tests/test_failures.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/tests/test_providers.py +0 -0
- {nextloop-0.1.0rc1 → nextloop-0.1.0rc2}/tests/test_stores.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nextloop
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0rc2
|
|
4
4
|
Summary: An embeddable AgentLoop with explicit event, tool, recovery, and delivery semantics
|
|
5
5
|
Author-email: 12bitsD <bis12@163.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -30,12 +30,12 @@ Dynamic: license-file
|
|
|
30
30
|
|
|
31
31
|
A small, embeddable Python AgentLoop with explicit execution, recovery, and delivery semantics.
|
|
32
32
|
|
|
33
|
-
Current version: **0.1.
|
|
33
|
+
Current version: **0.1.0rc2**.
|
|
34
34
|
|
|
35
35
|
## Install
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
python -m pip install nextloop==0.1.
|
|
38
|
+
python -m pip install nextloop==0.1.0rc2
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
For local development:
|
|
@@ -123,11 +123,12 @@ The release-candidate checks cover:
|
|
|
123
123
|
- resource-lock recovery, conflict prevention, and explicit release;
|
|
124
124
|
- real subprocess exits during Tool execution and final delivery, followed by SQLite recovery;
|
|
125
125
|
- recorded OpenAI and Anthropic SSE streams;
|
|
126
|
+
- 12 live Kimi scenarios across both protocols, real Tool usage, parallel execution, recovery, steer, cancellation, Compaction, and WorkingContext;
|
|
126
127
|
- `ruff`, `mypy`, wheel/sdist builds, `twine check`, and clean wheel installation.
|
|
127
128
|
|
|
128
129
|
Current limits:
|
|
129
130
|
|
|
130
|
-
-
|
|
131
|
+
- nika integration is separate acceptance work.
|
|
131
132
|
- Concurrent writers across multiple processes fail closed; they are not coordinated.
|
|
132
133
|
- Large-asset lifecycle, backup, and GC are not part of this release candidate.
|
|
133
134
|
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
A small, embeddable Python AgentLoop with explicit execution, recovery, and delivery semantics.
|
|
4
4
|
|
|
5
|
-
Current version: **0.1.
|
|
5
|
+
Current version: **0.1.0rc2**.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
python -m pip install nextloop==0.1.
|
|
10
|
+
python -m pip install nextloop==0.1.0rc2
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
For local development:
|
|
@@ -95,11 +95,12 @@ The release-candidate checks cover:
|
|
|
95
95
|
- resource-lock recovery, conflict prevention, and explicit release;
|
|
96
96
|
- real subprocess exits during Tool execution and final delivery, followed by SQLite recovery;
|
|
97
97
|
- recorded OpenAI and Anthropic SSE streams;
|
|
98
|
+
- 12 live Kimi scenarios across both protocols, real Tool usage, parallel execution, recovery, steer, cancellation, Compaction, and WorkingContext;
|
|
98
99
|
- `ruff`, `mypy`, wheel/sdist builds, `twine check`, and clean wheel installation.
|
|
99
100
|
|
|
100
101
|
Current limits:
|
|
101
102
|
|
|
102
|
-
-
|
|
103
|
+
- nika integration is separate acceptance work.
|
|
103
104
|
- Concurrent writers across multiple processes fail closed; they are not coordinated.
|
|
104
105
|
- Large-asset lifecycle, backup, and GC are not part of this release candidate.
|
|
105
106
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "nextloop"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.0rc2"
|
|
8
8
|
description = "An embeddable AgentLoop with explicit event, tool, recovery, and delivery semantics"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -7,6 +7,7 @@ from collections.abc import Sequence
|
|
|
7
7
|
|
|
8
8
|
from ..contracts import (
|
|
9
9
|
Event,
|
|
10
|
+
EventType,
|
|
10
11
|
InvariantViolation,
|
|
11
12
|
NewEvent,
|
|
12
13
|
SurfaceOp,
|
|
@@ -69,7 +70,11 @@ class InMemoryEventStore:
|
|
|
69
70
|
return tuple(
|
|
70
71
|
copy.deepcopy(event)
|
|
71
72
|
for event in events
|
|
72
|
-
if event.seq >= epoch_seq
|
|
73
|
+
if event.seq >= epoch_seq
|
|
74
|
+
and (
|
|
75
|
+
event.surface_op != SurfaceOp.NONE
|
|
76
|
+
or event.event_type == EventType.TOOL_BATCH_REJECTED
|
|
77
|
+
)
|
|
73
78
|
)
|
|
74
79
|
|
|
75
80
|
async def load_recovery(self, session_id: str) -> Sequence[Event]:
|
|
@@ -173,7 +173,7 @@ class SQLiteEventStore:
|
|
|
173
173
|
SELECT MAX(seq) FROM session_events
|
|
174
174
|
WHERE session_id = ? AND surface_op = 'epoch'
|
|
175
175
|
), 1)
|
|
176
|
-
AND surface_op != 'none'
|
|
176
|
+
AND (surface_op != 'none' OR event_type = 'tool/batch-rejected')
|
|
177
177
|
ORDER BY seq
|
|
178
178
|
""",
|
|
179
179
|
(session_id, session_id),
|
|
@@ -93,6 +93,11 @@ def project_events(
|
|
|
93
93
|
config: LoopConfig,
|
|
94
94
|
tools: Sequence[ToolSpec],
|
|
95
95
|
) -> Projection:
|
|
96
|
+
rejected_steps = {
|
|
97
|
+
(event.turn, event.step)
|
|
98
|
+
for event in events
|
|
99
|
+
if event.event_type == EventType.TOOL_BATCH_REJECTED
|
|
100
|
+
}
|
|
96
101
|
messages = [Message(role="system", content=config.system_prompt)]
|
|
97
102
|
messages.extend(config.bootstrap_messages)
|
|
98
103
|
for event in events:
|
|
@@ -105,7 +110,19 @@ def project_events(
|
|
|
105
110
|
EventType.ASSISTANT_MESSAGE,
|
|
106
111
|
EventType.TOOL_RESULT,
|
|
107
112
|
):
|
|
108
|
-
|
|
113
|
+
message = message_from_data(event.payload["message"])
|
|
114
|
+
if (
|
|
115
|
+
event.event_type == EventType.ASSISTANT_MESSAGE
|
|
116
|
+
and (event.turn, event.step) in rejected_steps
|
|
117
|
+
):
|
|
118
|
+
if not message.content:
|
|
119
|
+
continue
|
|
120
|
+
message = Message(
|
|
121
|
+
role=message.role,
|
|
122
|
+
content=message.content,
|
|
123
|
+
provider_data=message.provider_data,
|
|
124
|
+
)
|
|
125
|
+
messages.append(message)
|
|
109
126
|
request = CandidateRequest(
|
|
110
127
|
session_id=session_id,
|
|
111
128
|
turn=turn,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nextloop
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0rc2
|
|
4
4
|
Summary: An embeddable AgentLoop with explicit event, tool, recovery, and delivery semantics
|
|
5
5
|
Author-email: 12bitsD <bis12@163.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -30,12 +30,12 @@ Dynamic: license-file
|
|
|
30
30
|
|
|
31
31
|
A small, embeddable Python AgentLoop with explicit execution, recovery, and delivery semantics.
|
|
32
32
|
|
|
33
|
-
Current version: **0.1.
|
|
33
|
+
Current version: **0.1.0rc2**.
|
|
34
34
|
|
|
35
35
|
## Install
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
python -m pip install nextloop==0.1.
|
|
38
|
+
python -m pip install nextloop==0.1.0rc2
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
For local development:
|
|
@@ -123,11 +123,12 @@ The release-candidate checks cover:
|
|
|
123
123
|
- resource-lock recovery, conflict prevention, and explicit release;
|
|
124
124
|
- real subprocess exits during Tool execution and final delivery, followed by SQLite recovery;
|
|
125
125
|
- recorded OpenAI and Anthropic SSE streams;
|
|
126
|
+
- 12 live Kimi scenarios across both protocols, real Tool usage, parallel execution, recovery, steer, cancellation, Compaction, and WorkingContext;
|
|
126
127
|
- `ruff`, `mypy`, wheel/sdist builds, `twine check`, and clean wheel installation.
|
|
127
128
|
|
|
128
129
|
Current limits:
|
|
129
130
|
|
|
130
|
-
-
|
|
131
|
+
- nika integration is separate acceptance work.
|
|
131
132
|
- Concurrent writers across multiple processes fail closed; they are not coordinated.
|
|
132
133
|
- Large-asset lifecycle, backup, and GC are not part of this release candidate.
|
|
133
134
|
|
|
@@ -117,6 +117,9 @@ async def test_invalid_batch_executes_nothing_then_corrects():
|
|
|
117
117
|
events = await store.load_recovery("s")
|
|
118
118
|
assert any(event.event_type == EventType.TOOL_BATCH_REJECTED for event in events)
|
|
119
119
|
assert not any(event.event_type == EventType.TOOL_CALL for event in events)
|
|
120
|
+
second_request = provider.requests[1]
|
|
121
|
+
assert all(not message.tool_calls for message in second_request.messages)
|
|
122
|
+
assert second_request.messages[-1].content.startswith("[Protocol correction]")
|
|
120
123
|
|
|
121
124
|
|
|
122
125
|
@pytest.mark.asyncio
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|