nisse-core: group modules into packages by architecture section
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m37s
CI / e2e (pull_request) Successful in 4m5s

A pure move; behaviour unchanged.

- models (L9, L7): llm, catalog, probe, render, render_anthropic, context
- log (L7, L6): canonical, views
- state (L8): store (was state), reconcile, worker, cancel, dump
- knowledge (L10, L6.4): vault, memory
- conversation (L5): transport, matrix
- execution (L13): ssh (was execution), testing
- authority (P3, P4, L4): actions
- gitea, oplog, envfile stay at the top until each gains a second module.

Every import, monkeypatch target, script and doc reference rewritten.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
This commit is contained in:
dongarandClaude Opus 5.5 committed 2026-10-13 21:16:09 +00:00
1 parent 06759d5d70
commit e351d0a74e
117 files changed
+291 -265

No files matched your search

+1 -1
View File
@@ -59,7 +59,7 @@ jobs:
- name: Install sshd - name: Install sshd
# The tests reach "the build VM" over real SSH, through a throwaway # The tests reach "the build VM" over real SSH, through a throwaway
# sshd the test fixture starts (nisse_core/testing.py). Skipped when the image has it; otherwise from # sshd the test fixture starts (nisse_core/execution/testing.py). Skipped when the image has it; otherwise from
# a kernel.org mirror: archive.ubuntu.com has been slow enough to add # a kernel.org mirror: archive.ubuntu.com has been slow enough to add
# minutes to every job. # minutes to every job.
run: scripts/ci-sshd.sh run: scripts/ci-sshd.sh
+2 -2
View File
@@ -5,8 +5,8 @@ from pathlib import Path
import pytest import pytest
from nisse_core.execution import SSHHost from nisse_core.execution.ssh import SSHHost
from nisse_core.testing import local_sshd from nisse_core.execution.testing import local_sshd
@pytest.fixture(scope="session") @pytest.fixture(scope="session")
+6 -2
View File
@@ -312,7 +312,7 @@ the live session's fixes in #119 and #122). `nisse-dev` runs only the loop.
**M3.1 Action classes and the fast path.** *Needs discussion.* **Done** (this PR). **M3.1 Action classes and the fast path.** *Needs discussion.* **Done** (this PR).
Harmless, contained and dangerous actions per agent (P3, D6), static fast-path rules. Harmless, contained and dangerous actions per agent (P3, D6), static fast-path rules.
- `nisse_core.actions` (the shared part, `nisse-core`'s first code): `Action`, - `nisse_core.authority.actions` (the shared part, `nisse-core`'s first code): `Action`,
`Verdict`, and reading shell commands statically, segment by segment (`cd`, `Verdict`, and reading shell commands statically, segment by segment (`cd`,
wrappers like `sudo` and `timeout`, `sh -c`); what can't be read that way is wrappers like `sudo` and `timeout`, `sh -c`); what can't be read that way is
unknown, and a line is as bad as its worst command. unknown, and a line is as bad as its worst command.
@@ -567,7 +567,7 @@ the vault and memory, logging, `.env` loading, and the Gitea client (whole: L1
makes Gitea every agent's tracker). `nisse-core` never imports an agent (a test makes Gitea every agent's tracker). `nisse-core` never imports an agent (a test
says so). says so).
- `nisse_core.state.StateStore` holds the tables every agent has; an agent's - `nisse_core.state.store.StateStore` holds the tables every agent has; an agent's
subclass adds its own tables (with their schema version and migrations), its subclass adds its own tables (with their schema version and migrations), its
model roles, and what each role is shown of the others (`views`). model roles, and what each role is shown of the others (`views`).
`nisse_dev.state.StateStore` adds the build VM blocks (D3); stores already at `nisse_dev.state.StateStore` adds the build VM blocks (D3); stores already at
@@ -578,6 +578,10 @@ says so).
agent's `git`, delegation, `ask_expert`, executor tools and evaluation capture agent's `git`, delegation, `ask_expert`, executor tools and evaluation capture
stay in `nisse-dev`. stay in `nisse-dev`.
**Core packages.** *Done.* `nisse-core`'s modules grouped into packages by
architecture section (`models`, `log`, `state`, `knowledge`, `conversation`,
`execution`, `authority`), as a pure move ahead of M7.2.
**M7.2 Share the loop.** *Needs discussion.* What of `nisse_dev.loop` and **M7.2 Share the loop.** *Needs discussion.* What of `nisse_dev.loop` and
`config` is any agent's moves to `nisse-core`, shaped by what `nisse-review` `config` is any agent's moves to `nisse-core`, shaped by what `nisse-review`
needs; `nisse-dev` runs on it unchanged. needs; `nisse-dev` runs on it unchanged.
+19 -17
View File
@@ -1,22 +1,24 @@
# nisse-core # nisse-core
The shared library the Nisse agents sit on (Part L of the architecture). It The shared library the Nisse agents sit on (Part L of the architecture). It
never imports an agent. never imports an agent. Packages follow the architecture's sections:
- **Transcript and models:** `canonical` (the log's events, L7), `render` and - `models` (L9, L7): `llm` (the one client), `catalog` and `probe` (what the
`render_anthropic`, `llm` (the one client, L9), `catalog` and `probe` (what models are), `render` and `render_anthropic` (request bodies from the log),
the models are), `context` (fitting a request to its window, L6), `views` `context` (fitting a request to its window, L6).
(what each role is shown of the others). - `log` (L7, L6): `canonical` (the log's events), `views` (what each role is
- **Durability:** `state` (the store, L8; an agent subclasses it for its own shown of the others).
tables, roles and views), `reconcile`, `worker`, `cancel`, `dump`. - `state` (L8): `store` (an agent subclasses `StateStore` for its own tables,
- **Conversation:** `transport`, `matrix` (L5). roles and views), `reconcile`, `worker`, `cancel`, `dump`.
- **Execution:** `execution` (SSH to a tool VM, L13); `testing` (a throwaway - `knowledge` (L10, L6.4): `vault`, `memory`.
sshd for tests). - `conversation` (L5): `transport`, `matrix`.
- **Knowledge:** `vault` (L10), `memory` (L6.4). - `execution` (L13): `ssh` (SSH to a tool VM); `testing` (a throwaway sshd for
- **Operations:** `oplog`, `envfile` (L12); `gitea` (the tracker and forge, L1). tests).
- **Authority:** `actions` (P3, P4, L4): `Action`, `Verdict`, and static - `authority` (P3, P4, L4): `actions` (`Action`, `Verdict`, and static reading of
reading of shell commands, which each agent's fast-path rules build on shell commands, which each agent's fast-path rules build on; `nisse-dev`'s are
(`nisse-dev`'s are in `nisse_dev.loop.actions`). in `nisse_dev.loop.actions`).
- At the top, until each gains a second module: `gitea` (the tracker and forge,
L1), `oplog` and `envfile` (L12).
The loop is still `nisse-dev`'s, until `nisse-ops` has one to share it with The parts of a loop (`loop`) and shared configuration arrive with Development
(Development Plan M7.2). Plan M7.2; each agent keeps its own scheduler.
@@ -0,0 +1 @@
"""Actions by their effects (architecture P3, P4, L3, L4)."""
@@ -0,0 +1 @@
"""Conversation with the operator (architecture L5)."""
@@ -27,7 +27,7 @@ from urllib.parse import unquote
import httpx import httpx
from nisse_core.transport import InboundMessage from nisse_core.conversation.transport import InboundMessage
# A mention pill at the start of an HTML body: the link holds the user ID, # A mention pill at the start of an HTML body: the link holds the user ID,
# the link text is what the plain body starts with. # the link text is what the plain body starts with.
@@ -0,0 +1 @@
"""Running commands on tool VMs over SSH (architecture L13)."""
@@ -14,7 +14,7 @@ from collections.abc import Iterator
from contextlib import contextmanager from contextlib import contextmanager
from pathlib import Path from pathlib import Path
from nisse_core.execution import SSHHost from nisse_core.execution.ssh import SSHHost
SSHD = "/usr/sbin/sshd" SSHD = "/usr/sbin/sshd"
+2 -2
View File
@@ -16,8 +16,8 @@ from typing import Any
import httpx import httpx
from nisse_core.reconcile import Reconciler from nisse_core.state.reconcile import Reconciler
from nisse_core.state import Intent from nisse_core.state.store import Intent
PR_PAGE_SIZE = 50 PR_PAGE_SIZE = 50
MAX_PR_PAGES = 40 # 2000 PRs; beyond that, say so rather than guess MAX_PR_PAGES = 40 # 2000 PRs; beyond that, say so rather than guess
@@ -0,0 +1 @@
"""The knowledge vault (architecture L10) and agent memory (L6.4)."""
@@ -14,7 +14,7 @@ from dataclasses import dataclass
import yaml import yaml
from nisse_core.vault import Vault, VaultError, split_frontmatter from nisse_core.knowledge.vault import Vault, VaultError, split_frontmatter
INDEX = "index" # the note the harness keeps; never the model's INDEX = "index" # the note the harness keeps; never the model's
_NAME = re.compile(r"[a-z0-9][a-z0-9-]{0,63}") _NAME = re.compile(r"[a-z0-9][a-z0-9-]{0,63}")
@@ -0,0 +1,2 @@
"""The canonical log (architecture L7) and what each role is shown of it
(L6)."""
@@ -20,7 +20,7 @@ ranges still line up with the log. Everything not the viewer's own becomes a
from collections.abc import Mapping from collections.abc import Mapping
from dataclasses import replace from dataclasses import replace
from nisse_core.canonical import ( from nisse_core.log.canonical import (
ActionVerdict, ActionVerdict,
AssistantText, AssistantText,
DelegationCompleted, DelegationCompleted,
@@ -0,0 +1,2 @@
"""Talking to models (architecture L9): the client, what the models are, and
the request bodies built from the log (L7)."""
@@ -19,7 +19,7 @@ from typing import Any
import httpx import httpx
from nisse_core.llm import LLMClient, LLMError from nisse_core.models.llm import LLMClient, LLMError
# LiteLLM's provider name for models we have a vendor-native adapter for. # LiteLLM's provider name for models we have a vendor-native adapter for.
ANTHROPIC_PROVIDER = "anthropic" ANTHROPIC_PROVIDER = "anthropic"
@@ -28,7 +28,7 @@ from collections.abc import Callable, Sequence
from dataclasses import dataclass, replace from dataclasses import dataclass, replace
from typing import Any from typing import Any
from nisse_core.canonical import ( from nisse_core.log.canonical import (
AssistantText, AssistantText,
CanonicalEvent, CanonicalEvent,
DelegationStarted, DelegationStarted,
@@ -38,7 +38,7 @@ from nisse_core.canonical import (
ToolResult, ToolResult,
UserMessage, UserMessage,
) )
from nisse_core.llm import DEFAULT_MAX_OUTPUT_TOKENS, LLMError from nisse_core.models.llm import DEFAULT_MAX_OUTPUT_TOKENS, LLMError
# English and code run at about four characters a token. Three is deliberately # English and code run at about four characters a token. Three is deliberately
# pessimistic, before any correction from what the server reports. # pessimistic, before any correction from what the server reports.
@@ -17,15 +17,15 @@ from typing import Any, ClassVar, Protocol
import httpx import httpx
from nisse_core.canonical import ( from nisse_core.log.canonical import (
AssistantText, AssistantText,
CanonicalEvent, CanonicalEvent,
StoredEvent, StoredEvent,
ToolCall, ToolCall,
mint_call_id, mint_call_id,
) )
from nisse_core.render import OpenAIChatRenderer from nisse_core.models.render import OpenAIChatRenderer
from nisse_core.render_anthropic import AnthropicMessagesRenderer from nisse_core.models.render_anthropic import AnthropicMessagesRenderer
class LLMError(RuntimeError): class LLMError(RuntimeError):
@@ -24,7 +24,7 @@ from dataclasses import dataclass
import httpx import httpx
from nisse_core.catalog import ModelFacts from nisse_core.models.catalog import ModelFacts
# Of a probe's size, how much must come back for it to count as uncut. A # Of a probe's size, how much must come back for it to count as uncut. A
# chat template adds a little, and a tokenizer counts a little differently. # chat template adds a little, and a tokenizer counts a little differently.
@@ -11,7 +11,7 @@ this skeleton.
import json import json
from typing import Any from typing import Any
from nisse_core.canonical import ( from nisse_core.log.canonical import (
AssistantText, AssistantText,
Compaction, Compaction,
DelegationCompleted, DelegationCompleted,
@@ -18,7 +18,7 @@ route and this renderer builds the vendor-native body.
from typing import Any from typing import Any
from nisse_core.canonical import ( from nisse_core.log.canonical import (
AssistantText, AssistantText,
Compaction, Compaction,
DelegationCompleted, DelegationCompleted,
@@ -31,7 +31,7 @@ from nisse_core.canonical import (
ToolResult, ToolResult,
UserMessage, UserMessage,
) )
from nisse_core.render import effective_events from nisse_core.models.render import effective_events
DEFAULT_MAX_TOKENS = 4096 DEFAULT_MAX_TOKENS = 4096
NO_RESULT_PLACEHOLDER = "[no result recorded]" NO_RESULT_PLACEHOLDER = "[no result recorded]"
@@ -0,0 +1,2 @@
"""Durability (architecture L8): the state store, reconciliation, the worker
thread and the kill switch."""
@@ -8,8 +8,8 @@ record of a stop is written by the worker when the stopped work returns.
import threading import threading
from nisse_core.canonical import ToolCall, ToolResult from nisse_core.log.canonical import ToolCall, ToolResult
from nisse_core.state import Transcript from nisse_core.state.store import Transcript
STOPPED_RESULT = "not run: the operator stopped the agent" STOPPED_RESULT = "not run: the operator stopped the agent"
@@ -1,6 +1,6 @@
"""A readable dump of a state store, for bring-up runs and debugging. """A readable dump of a state store, for bring-up runs and debugging.
python -m nisse_core.dump STATE_DB [--full] python -m nisse_core.state.dump STATE_DB [--full]
Opens the store read-only (SQLite `mode=ro`), so it is safe to run against a Opens the store read-only (SQLite `mode=ro`), so it is safe to run against a
live agent's database: it never migrates, writes or locks it. Prints the work live agent's database: it never migrates, writes or locks it. Prints the work
@@ -11,7 +11,7 @@ from collections.abc import Callable, Mapping
from dataclasses import dataclass from dataclasses import dataclass
from typing import Literal from typing import Literal
from nisse_core.state import Intent, StateStore from nisse_core.state.store import Intent, StateStore
# Returns True if the intent's external effect verifiably happened (do not # Returns True if the intent's external effect verifiably happened (do not
# repeat it), False if it verifiably never started (safe to discard), or # repeat it), False if it verifiably never started (safe to discard), or
@@ -6,7 +6,7 @@ intent-log write is a single immediately-committed statement — in-memory state
that hasn't hit disk is assumed lost. that hasn't hit disk is assumed lost.
The intent log records a unit of work *before* it starts, so a restart knows The intent log records a unit of work *before* it starts, so a restart knows
what was in flight (see ``nisse_core.reconcile`` for how pending intents are what was in flight (see ``nisse_core.state.reconcile`` for how pending intents are
resolved against external truth on boot). resolved against external truth on boot).
""" """
@@ -18,7 +18,7 @@ from datetime import UTC, datetime
from pathlib import Path from pathlib import Path
from typing import Any, Self from typing import Any, Self
from nisse_core.canonical import ( from nisse_core.log.canonical import (
CanonicalEvent, CanonicalEvent,
StoredEvent, StoredEvent,
UserMessage, UserMessage,
@@ -26,8 +26,8 @@ from nisse_core.canonical import (
from_payload, from_payload,
to_payload, to_payload,
) )
from nisse_core.log.views import project
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.views import project
# The tables every agent has. An agent's own tables come on top: a subclass # The tables every agent has. An agent's own tables come on top: a subclass
# names them, the version they bring, and the migrations to it. # names them, the version they bring, and the migrations to it.
+1 -1
View File
@@ -1,6 +1,6 @@
import pytest import pytest
from nisse_core.actions import ( from nisse_core.authority.actions import (
CONTAINED, CONTAINED,
DANGEROUS, DANGEROUS,
HARMLESS, HARMLESS,
+2 -2
View File
@@ -3,7 +3,7 @@ from pathlib import Path
import pytest import pytest
from nisse_core.canonical import ( from nisse_core.log.canonical import (
AssistantText, AssistantText,
Compaction, Compaction,
DelegationCompleted, DelegationCompleted,
@@ -16,7 +16,7 @@ from nisse_core.canonical import (
from_payload, from_payload,
mint_call_id, mint_call_id,
) )
from nisse_core.state import StateSchemaError, StateStore from nisse_core.state.store import StateSchemaError, StateStore
ALL_EVENTS = [ ALL_EVENTS = [
UserMessage(text="use demo", source="matrix:$abc"), UserMessage(text="use demo", source="matrix:$abc"),
+1 -1
View File
@@ -8,7 +8,7 @@ route has to come from what LiteLLM says the model is.
import httpx import httpx
import pytest import pytest
from nisse_core.catalog import ( from nisse_core.models.catalog import (
CatalogUnavailable, CatalogUnavailable,
ModelCatalog, ModelCatalog,
UnknownModel, UnknownModel,
+4 -4
View File
@@ -6,7 +6,7 @@ from typing import Any
import pytest import pytest
from nisse_core.canonical import ( from nisse_core.log.canonical import (
AssistantText, AssistantText,
CanonicalEvent, CanonicalEvent,
StoredEvent, StoredEvent,
@@ -14,8 +14,8 @@ from nisse_core.canonical import (
ToolResult, ToolResult,
UserMessage, UserMessage,
) )
from nisse_core.catalog import ModelCatalog, UnknownLimits from nisse_core.models.catalog import ModelCatalog, UnknownLimits
from nisse_core.context import ( from nisse_core.models.context import (
Budget, Budget,
BudgetedClient, BudgetedClient,
ContextOverflow, ContextOverflow,
@@ -24,7 +24,7 @@ from nisse_core.context import (
head_and_tail, head_and_tail,
) )
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.state import StateStore from nisse_core.state.store import StateStore
from nisse_dev.loop.driver import Driver from nisse_dev.loop.driver import Driver
+9 -3
View File
@@ -1,10 +1,16 @@
import io import io
from pathlib import Path from pathlib import Path
from nisse_core.canonical import Fact, PlanSubmitted, ToolCall, ToolResult, UserMessage from nisse_core.log.canonical import (
from nisse_core.dump import main, render Fact,
PlanSubmitted,
ToolCall,
ToolResult,
UserMessage,
)
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.state import StateStore from nisse_core.state.dump import main, render
from nisse_core.state.store import StateStore
def store_with_a_run(path: Path) -> None: def store_with_a_run(path: Path) -> None:
+2 -2
View File
@@ -5,7 +5,7 @@ from pathlib import Path
import pytest import pytest
from nisse_core.execution import REDACTED, HostUnavailable, SSHHost, redact from nisse_core.execution.ssh import REDACTED, HostUnavailable, SSHHost, redact
def test_exit_codes_and_streams_come_back(ssh_host: SSHHost) -> None: def test_exit_codes_and_streams_come_back(ssh_host: SSHHost) -> None:
@@ -82,7 +82,7 @@ def test_a_changed_host_key_is_its_own_failure_and_only_forgetting_clears_it(
) -> None: ) -> None:
import subprocess import subprocess
from nisse_core.execution import HostKeyChanged from nisse_core.execution.ssh import HostKeyChanged
host = SSHHost( host = SSHHost(
ssh_host.address, ssh_host.address,
+1 -1
View File
@@ -10,7 +10,7 @@ from nisse_core.gitea import (
GiteaError, GiteaError,
pull_request_reconciler, pull_request_reconciler,
) )
from nisse_core.state import Intent from nisse_core.state.store import Intent
INTENT = Intent( INTENT = Intent(
id=1, id=1,
+3 -3
View File
@@ -5,14 +5,14 @@ from typing import Any
import httpx import httpx
import pytest import pytest
from nisse_core.canonical import ( from nisse_core.envfile import load_env_file
from nisse_core.log.canonical import (
AssistantText, AssistantText,
StoredEvent, StoredEvent,
ToolCall, ToolCall,
UserMessage, UserMessage,
) )
from nisse_core.envfile import load_env_file from nisse_core.models.llm import (
from nisse_core.llm import (
DEFAULT_MAX_OUTPUT_TOKENS, DEFAULT_MAX_OUTPUT_TOKENS,
OUTAGE_BACKOFF_S, OUTAGE_BACKOFF_S,
RATE_LIMIT_RETRY_S, RATE_LIMIT_RETRY_S,
+3 -3
View File
@@ -4,8 +4,8 @@ import threading
import httpx import httpx
import pytest import pytest
from nisse_core.matrix import MatrixConfig, MatrixTransport, TransportError from nisse_core.conversation.matrix import MatrixConfig, MatrixTransport, TransportError
from nisse_core.transport import InboundMessage from nisse_core.conversation.transport import InboundMessage
CONFIG = MatrixConfig( CONFIG = MatrixConfig(
homeserver="https://matrix.test", homeserver="https://matrix.test",
@@ -349,7 +349,7 @@ def test_a_reply_to_the_operators_own_threaded_message_joins_the_thread() -> Non
def test_in_memory_transport_plays_threads() -> None: def test_in_memory_transport_plays_threads() -> None:
from nisse_core.transport import InMemoryTransport from nisse_core.conversation.transport import InMemoryTransport
transport = InMemoryTransport() transport = InMemoryTransport()
seen: list[InboundMessage] = [] seen: list[InboundMessage] = []
+2 -2
View File
@@ -5,8 +5,8 @@ from pathlib import Path
import pytest import pytest
from nisse_core.memory import Memory from nisse_core.knowledge.memory import Memory
from nisse_core.vault import Vault, VaultError, split_frontmatter from nisse_core.knowledge.vault import Vault, VaultError, split_frontmatter
FOLDER = "memory/nisse-dev" FOLDER = "memory/nisse-dev"
+2 -2
View File
@@ -9,8 +9,8 @@ from pathlib import Path
import pytest import pytest
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.reconcile import reconcile_on_boot from nisse_core.state.reconcile import reconcile_on_boot
from nisse_core.state import StateStore from nisse_core.state.store import StateStore
ENVELOPE_FIELDS = {"ts", "agent", "event", "task_id", "cause"} ENVELOPE_FIELDS = {"ts", "agent", "event", "task_id", "cause"}
+1 -1
View File
@@ -2,7 +2,7 @@ import json
import httpx import httpx
from nisse_core.probe import interpret, probe from nisse_core.models.probe import interpret, probe
def test_a_cut_at_the_declared_window_matches() -> None: def test_a_cut_at_the_declared_window_matches() -> None:
+2 -2
View File
@@ -2,8 +2,8 @@ from pathlib import Path
import pytest import pytest
from nisse_core.reconcile import reconcile_on_boot from nisse_core.state.reconcile import reconcile_on_boot
from nisse_core.state import Intent, StateStore from nisse_core.state.store import Intent, StateStore
@pytest.fixture @pytest.fixture
+2 -2
View File
@@ -1,7 +1,7 @@
import json import json
from itertools import pairwise from itertools import pairwise
from nisse_core.canonical import ( from nisse_core.log.canonical import (
AssistantText, AssistantText,
Compaction, Compaction,
GateOpened, GateOpened,
@@ -10,7 +10,7 @@ from nisse_core.canonical import (
ToolResult, ToolResult,
UserMessage, UserMessage,
) )
from nisse_core.render import OpenAIChatRenderer, effective_events from nisse_core.models.render import OpenAIChatRenderer, effective_events
def stored(events: list) -> list[StoredEvent]: def stored(events: list) -> list[StoredEvent]:
+3 -3
View File
@@ -4,7 +4,7 @@ these tests pin the differences that a normalising middlebox would blur."""
import httpx import httpx
import pytest import pytest
from nisse_core.canonical import ( from nisse_core.log.canonical import (
AssistantText, AssistantText,
Compaction, Compaction,
StoredEvent, StoredEvent,
@@ -12,8 +12,8 @@ from nisse_core.canonical import (
ToolResult, ToolResult,
UserMessage, UserMessage,
) )
from nisse_core.llm import AnthropicPassthroughClient, LLMError from nisse_core.models.llm import AnthropicPassthroughClient, LLMError
from nisse_core.render_anthropic import ( from nisse_core.models.render_anthropic import (
AnthropicMessagesRenderer, AnthropicMessagesRenderer,
to_anthropic_tools, to_anthropic_tools,
) )
+1 -1
View File
@@ -3,7 +3,7 @@ from pathlib import Path
import pytest import pytest
from nisse_core.state import StateSchemaError, StateStore from nisse_core.state.store import StateSchemaError, StateStore
@pytest.fixture @pytest.fixture
+2 -2
View File
@@ -9,8 +9,8 @@ from pathlib import Path
import pytest import pytest
import yaml import yaml
from nisse_core import vault as vault_module from nisse_core.knowledge import vault as vault_module
from nisse_core.vault import Vault, VaultError, split_frontmatter from nisse_core.knowledge.vault import Vault, VaultError, split_frontmatter
@pytest.fixture @pytest.fixture
+4 -4
View File
@@ -4,7 +4,7 @@ import io
from collections.abc import Mapping from collections.abc import Mapping
from pathlib import Path from pathlib import Path
from nisse_core.canonical import ( from nisse_core.log.canonical import (
AssistantText, AssistantText,
DelegationCompleted, DelegationCompleted,
DelegationStarted, DelegationStarted,
@@ -15,10 +15,10 @@ from nisse_core.canonical import (
ToolResult, ToolResult,
UserMessage, UserMessage,
) )
from nisse_core.models.render import OpenAIChatRenderer
from nisse_core.models.render_anthropic import AnthropicMessagesRenderer
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.render import OpenAIChatRenderer from nisse_core.state.store import StateStore
from nisse_core.render_anthropic import AnthropicMessagesRenderer
from nisse_core.state import StateStore
class Store(StateStore): class Store(StateStore):
+2 -2
View File
@@ -5,8 +5,8 @@ from pathlib import Path
import pytest import pytest
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.state import StateStore from nisse_core.state.store import StateStore
from nisse_core.worker import InlineWorker, SerialWorker from nisse_core.state.worker import InlineWorker, SerialWorker
@pytest.fixture @pytest.fixture
+3 -3
View File
@@ -11,7 +11,8 @@ from datetime import UTC, datetime
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
from nisse_core.canonical import ( from nisse_core.execution.ssh import SSHHost
from nisse_core.log.canonical import (
CanonicalEvent, CanonicalEvent,
Fact, Fact,
StoredEvent, StoredEvent,
@@ -19,8 +20,7 @@ from nisse_core.canonical import (
ToolResult, ToolResult,
UserMessage, UserMessage,
) )
from nisse_core.catalog import ModelFacts from nisse_core.models.catalog import ModelFacts
from nisse_core.execution import SSHHost
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_dev.bench.tasks import Task from nisse_dev.bench.tasks import Task
from nisse_dev.config import Tuning from nisse_dev.config import Tuning
+7 -3
View File
@@ -23,9 +23,13 @@ from typing import Any
import yaml import yaml
from nisse_core.llm import DEFAULT_MAX_OUTPUT_TOKENS, DEFAULT_REQUEST_TIMEOUT_S, RoleMap from nisse_core.conversation.matrix import MatrixConfig
from nisse_core.matrix import MatrixConfig from nisse_core.knowledge.vault import ACCESS, DEFAULT_IGNORE
from nisse_core.vault import ACCESS, DEFAULT_IGNORE from nisse_core.models.llm import (
DEFAULT_MAX_OUTPUT_TOKENS,
DEFAULT_REQUEST_TIMEOUT_S,
RoleMap,
)
DEFAULT_CONFIG_FILE = "nisse-dev.yaml" DEFAULT_CONFIG_FILE = "nisse-dev.yaml"
+5 -5
View File
@@ -28,8 +28,7 @@ from collections.abc import Callable
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Any, Literal from typing import Any, Literal
from nisse_core.cancel import Cancel, skip_calls from nisse_core.log.canonical import (
from nisse_core.canonical import (
AssistantText, AssistantText,
DelegationCompleted, DelegationCompleted,
DelegationStarted, DelegationStarted,
@@ -39,9 +38,10 @@ from nisse_core.canonical import (
ToolCall, ToolCall,
ToolResult, ToolResult,
) )
from nisse_core.llm import LLMClient, LLMError, UpstreamUnavailable from nisse_core.models.llm import LLMClient, LLMError, UpstreamUnavailable
from nisse_core.reconcile import Reconciler from nisse_core.state.cancel import Cancel, skip_calls
from nisse_core.state import Intent, Transcript from nisse_core.state.reconcile import Reconciler
from nisse_core.state.store import Intent, Transcript
from nisse_dev.git import GitError, GitRepo from nisse_dev.git import GitError, GitRepo
from nisse_dev.state import StateStore from nisse_dev.state import StateStore
from nisse_dev.tools import EXECUTION_TOOLS, MUTATING_TOOLS, Workspace from nisse_dev.tools import EXECUTION_TOOLS, MUTATING_TOOLS, Workspace
+1 -1
View File
@@ -15,7 +15,7 @@ from collections.abc import Iterable
from dataclasses import asdict, dataclass from dataclasses import asdict, dataclass
from typing import Any from typing import Any
from nisse_core.canonical import ( from nisse_core.log.canonical import (
ActionVerdict, ActionVerdict,
DelegationCompleted, DelegationCompleted,
DelegationStarted, DelegationStarted,
+3 -3
View File
@@ -26,14 +26,14 @@ import json
import re import re
from dataclasses import dataclass from dataclasses import dataclass
from nisse_core.canonical import ( from nisse_core.log.canonical import (
DelegationCompleted, DelegationCompleted,
DelegationStarted, DelegationStarted,
StoredEvent, StoredEvent,
UserMessage, UserMessage,
) )
from nisse_core.llm import LLMClient, LLMError, RoleMap from nisse_core.models.llm import LLMClient, LLMError, RoleMap
from nisse_core.state import Transcript from nisse_core.state.store import Transcript
EXPERT_ROLE = "expert" EXPERT_ROLE = "expert"
DEFAULT_BUDGET = 3 DEFAULT_BUDGET = 3
+1 -1
View File
@@ -21,7 +21,7 @@ import shlex
from dataclasses import dataclass, field from dataclasses import dataclass, field
from pathlib import Path from pathlib import Path
from nisse_core.execution import HostUnavailable, SSHHost from nisse_core.execution.ssh import HostUnavailable, SSHHost
TIMEOUT_S = 120 TIMEOUT_S = 120
+2 -2
View File
@@ -17,13 +17,13 @@ do, judged by code before anything runs.
and is logged. and is logged.
A rule never makes a command less severe than its worst part; what can't be A rule never makes a command less severe than its worst part; what can't be
read statically is unknown (nisse_core.actions). read statically is unknown (nisse_core.authority.actions).
""" """
import posixpath import posixpath
from collections.abc import Callable from collections.abc import Callable
from nisse_core.actions import ( from nisse_core.authority.actions import (
CONTAINED, CONTAINED,
DANGEROUS, DANGEROUS,
HARMLESS, HARMLESS,
+11 -11
View File
@@ -26,7 +26,7 @@ from dataclasses import dataclass, replace
from datetime import UTC, datetime from datetime import UTC, datetime
from typing import Any from typing import Any
from nisse_core.actions import ( from nisse_core.authority.actions import (
CONTAINED, CONTAINED,
DANGEROUS, DANGEROUS,
REFUSED, REFUSED,
@@ -34,8 +34,12 @@ from nisse_core.actions import (
Action, Action,
Verdict, Verdict,
) )
from nisse_core.cancel import Cancel from nisse_core.conversation.transport import InboundMessage, Transport
from nisse_core.canonical import ( from nisse_core.execution.ssh import HostKeyChanged, HostUnavailable
from nisse_core.gitea import GiteaClient, GiteaError, Issue, PullRequest
from nisse_core.knowledge.memory import Memory
from nisse_core.knowledge.vault import Vault, VaultError
from nisse_core.log.canonical import (
ActionVerdict, ActionVerdict,
DelegationCompleted, DelegationCompleted,
DelegationStarted, DelegationStarted,
@@ -46,15 +50,11 @@ from nisse_core.canonical import (
ToolResult, ToolResult,
UserMessage, UserMessage,
) )
from nisse_core.execution import HostKeyChanged, HostUnavailable from nisse_core.models.llm import LLMError, RoleMap
from nisse_core.gitea import GiteaClient, GiteaError, Issue, PullRequest
from nisse_core.llm import LLMError, RoleMap
from nisse_core.memory import Memory
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.state import WorkItem from nisse_core.state.cancel import Cancel
from nisse_core.transport import InboundMessage, Transport from nisse_core.state.store import WorkItem
from nisse_core.vault import Vault, VaultError from nisse_core.state.worker import Worker
from nisse_core.worker import Worker
from nisse_dev.config import GENERAL from nisse_dev.config import GENERAL
from nisse_dev.delegation import DELEGATION_INTENT, Delegation from nisse_dev.delegation import DELEGATION_INTENT, Delegation
from nisse_dev.expert import BudgetExhausted, ExpertDesk from nisse_dev.expert import BudgetExhausted, ExpertDesk
+9 -9
View File
@@ -7,17 +7,17 @@ import threading
from collections.abc import Callable from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from nisse_core.cancel import Cancel from nisse_core.conversation.matrix import MatrixTransport
from nisse_core.catalog import ModelCatalog, select_client from nisse_core.execution.ssh import SSHHost
from nisse_core.context import BudgetedClient
from nisse_core.execution import SSHHost
from nisse_core.gitea import GiteaClient from nisse_core.gitea import GiteaClient
from nisse_core.llm import AnthropicPassthroughClient, LiteLLMClient from nisse_core.knowledge.memory import Memory
from nisse_core.matrix import MatrixTransport from nisse_core.knowledge.vault import Vault
from nisse_core.memory import Memory from nisse_core.models.catalog import ModelCatalog, select_client
from nisse_core.models.context import BudgetedClient
from nisse_core.models.llm import AnthropicPassthroughClient, LiteLLMClient
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.vault import Vault from nisse_core.state.cancel import Cancel
from nisse_core.worker import SerialWorker from nisse_core.state.worker import SerialWorker
from nisse_dev.config import AgentConfig, ConfigError from nisse_dev.config import AgentConfig, ConfigError
from nisse_dev.config import Project as ProjectEntry from nisse_dev.config import Project as ProjectEntry
from nisse_dev.delegation import Caps from nisse_dev.delegation import Caps
+3 -3
View File
@@ -16,9 +16,9 @@ from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any from typing import Any
from nisse_core.actions import CONTAINED, DANGEROUS, Action, Verdict from nisse_core.authority.actions import CONTAINED, DANGEROUS, Action, Verdict
from nisse_core.canonical import StoredEvent, ToolCall, UserMessage from nisse_core.log.canonical import StoredEvent, ToolCall, UserMessage
from nisse_core.llm import LLMClient, LLMError from nisse_core.models.llm import LLMClient, LLMError
SAFE = "safe" SAFE = "safe"
IN_SCOPE = "in_scope" IN_SCOPE = "in_scope"
+4 -4
View File
@@ -11,10 +11,10 @@ from collections.abc import Callable, Mapping
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, Literal from typing import Any, Literal
from nisse_core.cancel import Cancel, skip_calls from nisse_core.log.canonical import AssistantText, Fact, ToolCall, ToolResult
from nisse_core.canonical import AssistantText, Fact, ToolCall, ToolResult from nisse_core.models.llm import LLMClient, LLMError
from nisse_core.llm import LLMClient, LLMError from nisse_core.state.cancel import Cancel, skip_calls
from nisse_core.state import Transcript from nisse_core.state.store import Transcript
from nisse_dev.loop.tools import WAITING, names from nisse_dev.loop.tools import WAITING, names
from nisse_dev.tools import Workspace from nisse_dev.tools import Workspace
+1 -1
View File
@@ -11,7 +11,7 @@ half-edited tree).
from collections.abc import Callable, Mapping from collections.abc import Callable, Mapping
from dataclasses import dataclass, field from dataclasses import dataclass, field
from nisse_core.llm import LLMClient, RoleMap from nisse_core.models.llm import LLMClient, RoleMap
from nisse_dev.config import Profile from nisse_dev.config import Profile
from nisse_dev.delegation import Caps from nisse_dev.delegation import Caps
from nisse_dev.expert import DEFAULT_BUDGET from nisse_dev.expert import DEFAULT_BUDGET
+1 -1
View File
@@ -8,7 +8,7 @@ agreement, what it is waiting for) is in ``data["loop"]``.
from dataclasses import asdict, dataclass from dataclasses import asdict, dataclass
from typing import Any from typing import Any
from nisse_core.state import WorkItem from nisse_core.state.store import WorkItem
from nisse_dev.state import StateStore from nisse_dev.state import StateStore
READY = "ready" READY = "ready"
+2 -2
View File
@@ -20,8 +20,8 @@ import shlex
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Any from typing import Any
from nisse_core.actions import split_shell, unwrap from nisse_core.authority.actions import split_shell, unwrap
from nisse_core.execution import SSHHost from nisse_core.execution.ssh import SSHHost
# What the harness itself runs on a build VM (L13, D4): part of the # What the harness itself runs on a build VM (L13, D4): part of the
# template, never of a project's toolchain. # template, never of a project's toolchain.
+2 -2
View File
@@ -10,8 +10,8 @@ The driver's model reads for now; the classifier role takes over in M2.6.
from typing import Any from typing import Any
from nisse_core.canonical import StoredEvent, ToolCall, UserMessage from nisse_core.log.canonical import StoredEvent, ToolCall, UserMessage
from nisse_core.llm import LLMClient, LLMError from nisse_core.models.llm import LLMClient, LLMError
def command_form(text: str) -> str: def command_form(text: str) -> str:
+3 -3
View File
@@ -5,8 +5,8 @@ import sqlite3
from collections.abc import Mapping from collections.abc import Mapping
from dataclasses import dataclass from dataclasses import dataclass
from nisse_core import state from nisse_core.state import store as state
from nisse_core.state import Migration, utc_now from nisse_core.state.store import Migration, utc_now
_VM_BLOCKS = """ _VM_BLOCKS = """
CREATE TABLE vm_blocks ( CREATE TABLE vm_blocks (
@@ -48,7 +48,7 @@ class StateStore(state.StateStore):
"toolchain", # the toolchain step (D3): the driver's model, apart "toolchain", # the toolchain step (D3): the driver's model, apart
"memory", # the memory pass at an item's close (L6.4), apart too "memory", # the memory pass at an item's close (L6.4), apart too
} }
# What each role is shown of the others' work (``nisse_core.views``). # What each role is shown of the others' work (``nisse_core.log.views``).
SHOWN: Mapping[str, Mapping[str, str]] = { SHOWN: Mapping[str, Mapping[str, str]] = {
"driver": {"helper": "report"}, "driver": {"helper": "report"},
"helper": {"driver": "narrate"}, "helper": {"driver": "narrate"},
+2 -2
View File
@@ -20,8 +20,8 @@ from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
from nisse_core.context import head_and_tail from nisse_core.execution.ssh import HostUnavailable, Result, SSHHost
from nisse_core.execution import HostUnavailable, Result, SSHHost from nisse_core.models.context import head_and_tail
# Tools that change or verify something. Reading a file or listing a # Tools that change or verify something. Reading a file or listing a
# directory is a model looking around, not doing the work, so neither counts # directory is a model looking around, not doing the work, so neither counts
+2 -2
View File
@@ -10,8 +10,8 @@ unit tests and be rejected live; this makes it fail here.
from typing import Any from typing import Any
from nisse_core.render import OpenAIChatRenderer from nisse_core.models.render import OpenAIChatRenderer
from nisse_core.render_anthropic import AnthropicMessagesRenderer from nisse_core.models.render_anthropic import AnthropicMessagesRenderer
def assert_renderable(events: list[Any]) -> None: def assert_renderable(events: list[Any]) -> None:
+4 -4
View File
@@ -11,9 +11,9 @@ import httpx
import pytest import pytest
from test_config import SECRETS, P, tree from test_config import SECRETS, P, tree
from nisse_core.catalog import ModelCatalog, UnknownModel from nisse_core.execution.ssh import SSHHost
from nisse_core.execution import SSHHost from nisse_core.models.catalog import ModelCatalog, UnknownModel
from nisse_core.llm import AnthropicPassthroughClient, LiteLLMClient from nisse_core.models.llm import AnthropicPassthroughClient, LiteLLMClient
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_dev.config import AgentConfig from nisse_dev.config import AgentConfig
from nisse_dev.loop.build import RunningLoop, build_loop_agent, discover_models from nisse_dev.loop.build import RunningLoop, build_loop_agent, discover_models
@@ -143,7 +143,7 @@ def offline(monkeypatch: Any, origins: dict[str, str] | str, catalog=None) -> No
"""Only the network boundaries faked: Gitea, LiteLLM's model list, Matrix.""" """Only the network boundaries faked: Gitea, LiteLLM's model list, Matrix."""
# The proxy here doesn't exist: a call to it fails at once rather than # The proxy here doesn't exist: a call to it fails at once rather than
# waiting out an outage's backoff (L5). # waiting out an outage's backoff (L5).
monkeypatch.setattr("nisse_core.llm.OUTAGE_BACKOFF_S", ()) monkeypatch.setattr("nisse_core.models.llm.OUTAGE_BACKOFF_S", ())
monkeypatch.setattr( monkeypatch.setattr(
"nisse_dev.loop.build.GiteaClient.whoami", lambda self: "nisse-dev-testing" "nisse_dev.loop.build.GiteaClient.whoami", lambda self: "nisse-dev-testing"
) )
+3 -3
View File
@@ -7,9 +7,9 @@ from typing import Any
import pytest import pytest
from nisse_core.canonical import AssistantText, ToolCall from nisse_core.execution.ssh import SSHHost
from nisse_core.catalog import ModelFacts from nisse_core.log.canonical import AssistantText, ToolCall
from nisse_core.execution import SSHHost from nisse_core.models.catalog import ModelFacts
from nisse_dev.bench.results import ( from nisse_dev.bench.results import (
append, append,
load, load,
+2 -2
View File
@@ -5,7 +5,7 @@ from typing import Any
import pytest import pytest
from nisse_core.llm import DEFAULT_REQUEST_TIMEOUT_S from nisse_core.models.llm import DEFAULT_REQUEST_TIMEOUT_S
from nisse_dev.config import AgentConfig, ConfigError, Project from nisse_dev.config import AgentConfig, ConfigError, Project
# A complete config as the YAML file would give it, with secrets by reference. # A complete config as the YAML file would give it, with secrets by reference.
@@ -142,7 +142,7 @@ def test_request_timeout_is_configurable_and_checked() -> None:
def test_the_request_timeout_reaches_both_clients() -> None: def test_the_request_timeout_reaches_both_clients() -> None:
from nisse_core.catalog import ModelCatalog from nisse_core.models.catalog import ModelCatalog
from nisse_dev.loop.build import make_llm_clients from nisse_dev.loop.build import make_llm_clients
normalized, passthrough = make_llm_clients( normalized, passthrough = make_llm_clients(
+5 -5
View File
@@ -4,8 +4,8 @@ from typing import Any
import pytest import pytest
from nisse_core.cancel import STOPPED_RESULT, Cancel from nisse_core.execution.ssh import SSHHost
from nisse_core.canonical import ( from nisse_core.log.canonical import (
AssistantText, AssistantText,
CanonicalEvent, CanonicalEvent,
DelegationCompleted, DelegationCompleted,
@@ -14,10 +14,10 @@ from nisse_core.canonical import (
ToolCall, ToolCall,
ToolResult, ToolResult,
) )
from nisse_core.execution import SSHHost from nisse_core.models.llm import BudgetExhausted, LLMError, UpstreamUnavailable
from nisse_core.llm import BudgetExhausted, LLMError, UpstreamUnavailable
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.state import Transcript from nisse_core.state.cancel import STOPPED_RESULT, Cancel
from nisse_core.state.store import Transcript
from nisse_dev.delegation import ( from nisse_dev.delegation import (
DELEGATE_TOOLS, DELEGATE_TOOLS,
DELEGATION_INTENT, DELEGATION_INTENT,
+2 -2
View File
@@ -5,8 +5,8 @@ from pathlib import Path
import pytest import pytest
from nisse_core.canonical import ToolCall from nisse_core.log.canonical import ToolCall
from nisse_core.state import StateStore as CoreStore from nisse_core.state.store import StateStore as CoreStore
from nisse_dev.state import StateStore from nisse_dev.state import StateStore
+1 -1
View File
@@ -4,7 +4,7 @@ from pathlib import Path
import pytest import pytest
from nisse_core.canonical import ( from nisse_core.log.canonical import (
AssistantText, AssistantText,
DelegationCompleted, DelegationCompleted,
DelegationStarted, DelegationStarted,
+3 -3
View File
@@ -4,16 +4,16 @@ from typing import Any
import pytest import pytest
from nisse_core.canonical import ( from nisse_core.log.canonical import (
AssistantText, AssistantText,
CanonicalEvent, CanonicalEvent,
DelegationCompleted, DelegationCompleted,
DelegationStarted, DelegationStarted,
StoredEvent, StoredEvent,
) )
from nisse_core.llm import LLMError, RoleMap from nisse_core.models.llm import LLMError, RoleMap
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.state import Transcript from nisse_core.state.store import Transcript
from nisse_dev.expert import ( from nisse_dev.expert import (
DEFAULT_BUDGET, DEFAULT_BUDGET,
BudgetExhausted, BudgetExhausted,
+2 -2
View File
@@ -6,7 +6,7 @@ from pathlib import Path
import pytest import pytest
from nisse_core.execution import SSHHost from nisse_core.execution.ssh import SSHHost
from nisse_dev.git import GitError, GitRepo, HTTPSToken, SSHKey from nisse_dev.git import GitError, GitRepo, HTTPSToken, SSHKey
@@ -170,7 +170,7 @@ class RecordingHost:
self.calls: list[dict] = [] self.calls: list[dict] = []
def execute(self, command: str, **kwargs): def execute(self, command: str, **kwargs):
from nisse_core.execution import Result from nisse_core.execution.ssh import Result
self.calls.append({"command": command, **kwargs}) self.calls.append({"command": command, **kwargs})
return Result(0, "", "") return Result(0, "", "")
+7 -7
View File
@@ -8,19 +8,19 @@ from typing import Any
import pytest import pytest
from model_contract import assert_renderable from model_contract import assert_renderable
from nisse_core.cancel import Cancel from nisse_core.conversation.transport import InMemoryTransport
from nisse_core.canonical import ( from nisse_core.gitea import Issue
from nisse_core.log.canonical import (
AssistantText, AssistantText,
CanonicalEvent, CanonicalEvent,
Fact, Fact,
ToolCall, ToolCall,
ToolResult, ToolResult,
) )
from nisse_core.gitea import Issue from nisse_core.models.llm import LLMError
from nisse_core.llm import LLMError
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.transport import InMemoryTransport from nisse_core.state.cancel import Cancel
from nisse_core.worker import InlineWorker from nisse_core.state.worker import InlineWorker
from nisse_dev.loop.agent import LoopAgent from nisse_dev.loop.agent import LoopAgent
from nisse_dev.loop.driver import Driver from nisse_dev.loop.driver import Driver
from nisse_dev.loop.items import CLOSED, GO_AHEAD, READY, RUNNING, WAITING, loop_of from nisse_dev.loop.items import CLOSED, GO_AHEAD, READY, RUNNING, WAITING, loop_of
@@ -250,7 +250,7 @@ def test_a_go_for_an_earlier_revision_is_not_applied(h: Harness) -> None:
h.say("put it in its own module") # changes, so the driver restates rev-2 h.say("put it in its own module") # changes, so the driver restates rev-2
assert loop_of(h.item()).rev == 2 assert loop_of(h.item()).rev == 2
# A go sent while rev-1 was on screen, arriving now. # A go sent while rev-1 was on screen, arriving now.
from nisse_core.transport import InboundMessage from nisse_core.conversation.transport import InboundMessage
h.agent.handle(InboundMessage(DON, "go", thread=h.thread()), about=1) h.agent.handle(InboundMessage(DON, "go", thread=h.thread()), about=1)
assert not loop_of(h.item()).started assert not loop_of(h.item()).started
+2 -2
View File
@@ -11,8 +11,8 @@ from test_loop_milestones import RESTATE, ScriptedModel, call, loop_agent, say
from test_loop_milestones import item as the_item from test_loop_milestones import item as the_item
from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture
from nisse_core.actions import Action from nisse_core.authority.actions import Action
from nisse_core.canonical import ActionVerdict, ToolCall, ToolResult from nisse_core.log.canonical import ActionVerdict, ToolCall, ToolResult
from nisse_dev.loop.actions import classify, commits from nisse_dev.loop.actions import classify, commits
from nisse_dev.loop.items import ANSWER, loop_of from nisse_dev.loop.items import ANSWER, loop_of
+3 -3
View File
@@ -13,9 +13,9 @@ from test_loop_milestones import ScriptedModel, call, loop_agent, say
from test_loop_milestones import item as the_item from test_loop_milestones import item as the_item
from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture
from nisse_core.actions import Action from nisse_core.authority.actions import Action
from nisse_core.canonical import ActionVerdict, ToolCall from nisse_core.log.canonical import ActionVerdict, ToolCall
from nisse_core.llm import LLMError from nisse_core.models.llm import LLMError
from nisse_dev.loop.classifier import ActionClassifier, Scope from nisse_dev.loop.classifier import ActionClassifier, Scope
from nisse_dev.loop.items import ANSWER, loop_of from nisse_dev.loop.items import ANSWER, loop_of
+1 -1
View File
@@ -9,8 +9,8 @@ from typing import Any
from test_loop_milestones import DON, Forge, ScriptedModel, call, loop_agent from test_loop_milestones import DON, Forge, ScriptedModel, call, loop_agent
from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture
from nisse_core.canonical import Fact, ToolResult
from nisse_core.gitea import Issue from nisse_core.gitea import Issue
from nisse_core.log.canonical import Fact, ToolResult
from nisse_dev.loop.agent import FILE_ISSUE from nisse_dev.loop.agent import FILE_ISSUE
from nisse_dev.loop.items import CHAT, GO_AHEAD, MERGE, WAITING, loop_of from nisse_dev.loop.items import CHAT, GO_AHEAD, MERGE, WAITING, loop_of
+2 -2
View File
@@ -18,14 +18,14 @@ from test_loop_milestones import (
) )
from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture
from nisse_core.canonical import ( from nisse_core.log.canonical import (
AssistantText, AssistantText,
DelegationStarted, DelegationStarted,
Fact, Fact,
ToolCall, ToolCall,
ToolResult, ToolResult,
) )
from nisse_core.llm import RoleMap from nisse_core.models.llm import RoleMap
from nisse_dev.config import Profile from nisse_dev.config import Profile
from nisse_dev.delegation import DELEGATION_INTENT, Caps from nisse_dev.delegation import DELEGATION_INTENT, Caps
from nisse_dev.loop.help import Helpers from nisse_dev.loop.help import Helpers
+3 -3
View File
@@ -9,8 +9,8 @@ import pytest
from test_loop import DON, RESTATED, FakeGitea, Harness, ScriptedModel, call, issue from test_loop import DON, RESTATED, FakeGitea, Harness, ScriptedModel, call, issue
from test_loop import h as h # noqa: PLC0414 -- the fixture from test_loop import h as h # noqa: PLC0414 -- the fixture
from nisse_core.canonical import Fact, ToolCall from nisse_core.log.canonical import Fact, ToolCall
from nisse_core.llm import LLMError from nisse_core.models.llm import LLMError
from nisse_dev.loop.items import ANSWER, GO_AHEAD, READY, WAITING, loop_of from nisse_dev.loop.items import ANSWER, GO_AHEAD, READY, WAITING, loop_of
from nisse_dev.loop.reader import GoAheadReader from nisse_dev.loop.reader import GoAheadReader
@@ -284,7 +284,7 @@ def test_an_unlabelled_issue_waits_for_go_with_no_countdown(h: Harness) -> None:
def _msg(text: str, thread: str) -> Any: def _msg(text: str, thread: str) -> Any:
from nisse_core.transport import InboundMessage from nisse_core.conversation.transport import InboundMessage
return InboundMessage(DON, text, thread=thread) return InboundMessage(DON, text, thread=thread)
+1 -1
View File
@@ -16,8 +16,8 @@ from test_loop_milestones import RESTATE, Forge, loop_agent, say
from test_loop_milestones import item as the_item from test_loop_milestones import item as the_item
from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture
from nisse_core.canonical import AssistantText, Fact
from nisse_core.gitea import Comment from nisse_core.gitea import Comment
from nisse_core.log.canonical import AssistantText, Fact
from nisse_dev.delegation import Caps from nisse_dev.delegation import Caps
from nisse_dev.loop.help import Helpers from nisse_dev.loop.help import Helpers
from nisse_dev.loop.items import GO_AHEAD, MERGE, WAITING, loop_of from nisse_dev.loop.items import GO_AHEAD, MERGE, WAITING, loop_of
+4 -4
View File
@@ -12,10 +12,10 @@ from test_loop_milestones import item as the_item
from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture
from test_loop_notes import Spy from test_loop_notes import Spy
from nisse_core.canonical import AssistantText, Fact from nisse_core.knowledge.memory import Memory
from nisse_core.llm import RoleMap from nisse_core.knowledge.vault import Vault
from nisse_core.memory import Memory from nisse_core.log.canonical import AssistantText, Fact
from nisse_core.vault import Vault from nisse_core.models.llm import RoleMap
FOLDER = "memory/nisse-dev" FOLDER = "memory/nisse-dev"
+5 -5
View File
@@ -10,9 +10,8 @@ from typing import Any
import pytest import pytest
from model_contract import assert_renderable from model_contract import assert_renderable
from nisse_core.cancel import Cancel from nisse_core.conversation.transport import InMemoryTransport
from nisse_core.canonical import ToolCall from nisse_core.execution.ssh import SSHHost
from nisse_core.execution import SSHHost
from nisse_core.gitea import ( from nisse_core.gitea import (
Approval, Approval,
Comment, Comment,
@@ -21,9 +20,10 @@ from nisse_core.gitea import (
PullRequest, PullRequest,
ReviewNote, ReviewNote,
) )
from nisse_core.log.canonical import ToolCall
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.transport import InMemoryTransport from nisse_core.state.cancel import Cancel
from nisse_core.worker import InlineWorker from nisse_core.state.worker import InlineWorker
from nisse_dev.git import GitRepo from nisse_dev.git import GitRepo
from nisse_dev.loop.agent import LoopAgent from nisse_dev.loop.agent import LoopAgent
from nisse_dev.loop.driver import Driver from nisse_dev.loop.driver import Driver
+1 -1
View File
@@ -18,8 +18,8 @@ from test_loop_milestones import (
) )
from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture
from nisse_core.canonical import ToolCall, ToolResult
from nisse_core.gitea import Issue from nisse_core.gitea import Issue
from nisse_core.log.canonical import ToolCall, ToolResult
from nisse_dev.loop.items import MERGE, WAITING, loop_of from nisse_dev.loop.items import MERGE, WAITING, loop_of
+4 -4
View File
@@ -14,11 +14,11 @@ import yaml
from test_loop_milestones import DON, Forge, ScriptedModel, call, make_world from test_loop_milestones import DON, Forge, ScriptedModel, call, make_world
from test_loop_projects import Router from test_loop_projects import Router
from nisse_core.cancel import Cancel from nisse_core.conversation.transport import InMemoryTransport
from nisse_core.execution import SSHHost from nisse_core.execution.ssh import SSHHost
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.transport import InMemoryTransport from nisse_core.state.cancel import Cancel
from nisse_core.worker import InlineWorker from nisse_core.state.worker import InlineWorker
from nisse_dev.config import _parse_projects from nisse_dev.config import _parse_projects
from nisse_dev.loop.agent import LoopAgent, Project from nisse_dev.loop.agent import LoopAgent, Project
from nisse_dev.loop.driver import Driver from nisse_dev.loop.driver import Driver
+2 -2
View File
@@ -11,8 +11,8 @@ from test_loop_milestones import DON, RESTATE, ScriptedModel, call, loop_agent
from test_loop_milestones import item as the_item from test_loop_milestones import item as the_item
from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture
from nisse_core.canonical import ToolResult from nisse_core.knowledge.vault import Vault
from nisse_core.vault import Vault from nisse_core.log.canonical import ToolResult
from nisse_dev.loop.items import GO_AHEAD, loop_of from nisse_dev.loop.items import GO_AHEAD, loop_of
+4 -4
View File
@@ -10,11 +10,11 @@ from typing import Any
import pytest import pytest
from test_loop_milestones import DON, Forge, ScriptedModel, call, git, make_world from test_loop_milestones import DON, Forge, ScriptedModel, call, git, make_world
from nisse_core.cancel import Cancel from nisse_core.conversation.transport import InMemoryTransport
from nisse_core.execution import SSHHost from nisse_core.execution.ssh import SSHHost
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.transport import InMemoryTransport from nisse_core.state.cancel import Cancel
from nisse_core.worker import InlineWorker from nisse_core.state.worker import InlineWorker
from nisse_dev.loop.agent import LoopAgent, Project from nisse_dev.loop.agent import LoopAgent, Project
from nisse_dev.loop.driver import Driver from nisse_dev.loop.driver import Driver
from nisse_dev.loop.items import ANSWER, GO_AHEAD, MERGE, item_for_issue, loop_of from nisse_dev.loop.items import ANSWER, GO_AHEAD, MERGE, item_for_issue, loop_of
+9 -9
View File
@@ -24,8 +24,12 @@ from test_loop_milestones import DON, Forge, call, make_world
from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture
from test_loop_projects import Router from test_loop_projects import Router
from nisse_core.cancel import Cancel from nisse_core.conversation.transport import InboundMessage, InMemoryTransport
from nisse_core.canonical import ( from nisse_core.execution.ssh import HostUnavailable, SSHHost
from nisse_core.gitea import Comment, Issue
from nisse_core.knowledge.memory import Memory
from nisse_core.knowledge.vault import Vault, split_frontmatter
from nisse_core.log.canonical import (
ActionVerdict, ActionVerdict,
AssistantText, AssistantText,
Fact, Fact,
@@ -34,14 +38,10 @@ from nisse_core.canonical import (
ToolResult, ToolResult,
UserMessage, UserMessage,
) )
from nisse_core.execution import HostUnavailable, SSHHost from nisse_core.models.llm import LLMError, RoleMap
from nisse_core.gitea import Comment, Issue
from nisse_core.llm import LLMError, RoleMap
from nisse_core.memory import Memory
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.transport import InboundMessage, InMemoryTransport from nisse_core.state.cancel import Cancel
from nisse_core.vault import Vault, split_frontmatter from nisse_core.state.worker import InlineWorker
from nisse_core.worker import InlineWorker
from nisse_dev.delegation import DELEGATION_INTENT, Caps from nisse_dev.delegation import DELEGATION_INTENT, Caps
from nisse_dev.loop.agent import LoopAgent, Project from nisse_dev.loop.agent import LoopAgent, Project
from nisse_dev.loop.classifier import ActionClassifier from nisse_dev.loop.classifier import ActionClassifier
+1 -1
View File
@@ -7,8 +7,8 @@ from typing import Any
from test_loop_milestones import DON, Forge, ScriptedModel, call, git, loop_agent from test_loop_milestones import DON, Forge, ScriptedModel, call, git, loop_agent
from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture
from nisse_core.conversation.transport import InboundMessage, InMemoryTransport
from nisse_core.gitea import Comment, Issue from nisse_core.gitea import Comment, Issue
from nisse_core.transport import InboundMessage, InMemoryTransport
from nisse_dev.loop.items import ( from nisse_dev.loop.items import (
ANSWER, ANSWER,
BLOCKED, BLOCKED,
+1 -1
View File
@@ -8,7 +8,7 @@ from typing import Any
from test_loop import DON, RESTATED, FakeGitea, Harness, ScriptedModel, call, issue from test_loop import DON, RESTATED, FakeGitea, Harness, ScriptedModel, call, issue
from nisse_core.canonical import AssistantText from nisse_core.log.canonical import AssistantText
from nisse_dev.loop.items import ANSWER, GO_AHEAD, WAITING, loop_of from nisse_dev.loop.items import ANSWER, GO_AHEAD, WAITING, loop_of
+6 -6
View File
@@ -26,13 +26,13 @@ from test_loop_milestones import (
from test_loop_milestones import item as the_item from test_loop_milestones import item as the_item
from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture
from nisse_core.cancel import Cancel from nisse_core.conversation.transport import InMemoryTransport
from nisse_core.canonical import Fact, ToolResult from nisse_core.execution.ssh import HostKeyChanged
from nisse_core.execution import HostKeyChanged
from nisse_core.gitea import Issue from nisse_core.gitea import Issue
from nisse_core.log.canonical import Fact, ToolResult
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.transport import InMemoryTransport from nisse_core.state.cancel import Cancel
from nisse_core.worker import InlineWorker from nisse_core.state.worker import InlineWorker
from nisse_dev.loop import preflight from nisse_dev.loop import preflight
from nisse_dev.loop.agent import LoopAgent, Project from nisse_dev.loop.agent import LoopAgent, Project
from nisse_dev.loop.driver import Driver from nisse_dev.loop.driver import Driver
@@ -194,7 +194,7 @@ def test_what_was_installed_or_is_missing_is_said(
def test_an_unfinished_step_is_said_and_work_goes_on( def test_an_unfinished_step_is_said_and_work_goes_on(
world: dict[str, Any], project: str world: dict[str, Any], project: str
) -> None: ) -> None:
from nisse_core.canonical import AssistantText from nisse_core.log.canonical import AssistantText
prose = [AssistantText(text="hmm", model="m")] prose = [AssistantText(text="hmm", model="m")]
model = ScriptedModel(prose, prose, RESTATE) model = ScriptedModel(prose, prose, RESTATE)
+3 -3
View File
@@ -19,10 +19,10 @@ from test_loop_milestones import (
from test_loop_milestones import item as the_item from test_loop_milestones import item as the_item
from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture from test_loop_milestones import world as world # noqa: PLC0414 -- the fixture
from nisse_core.cancel import Cancel from nisse_core.conversation.transport import InMemoryTransport
from nisse_core.oplog import OpLog from nisse_core.oplog import OpLog
from nisse_core.transport import InMemoryTransport from nisse_core.state.cancel import Cancel
from nisse_core.worker import InlineWorker from nisse_core.state.worker import InlineWorker
from nisse_dev.loop.agent import LoopAgent, Project from nisse_dev.loop.agent import LoopAgent, Project
from nisse_dev.loop.driver import Driver from nisse_dev.loop.driver import Driver
from nisse_dev.loop.items import MERGE, loop_of from nisse_dev.loop.items import MERGE, loop_of
+2 -2
View File
@@ -19,9 +19,9 @@ from test_loop_toolchain import (
) )
from test_loop_toolchain import project as project # noqa: PLC0414 -- the fixture from test_loop_toolchain import project as project # noqa: PLC0414 -- the fixture
from nisse_core.canonical import ToolResult from nisse_core.execution.ssh import HostKeyChanged, HostUnavailable
from nisse_core.execution import HostKeyChanged, HostUnavailable
from nisse_core.gitea import Issue from nisse_core.gitea import Issue
from nisse_core.log.canonical import ToolResult
from nisse_dev.loop.items import GO_AHEAD, READY, loop_of from nisse_dev.loop.items import GO_AHEAD, READY, loop_of
RETRY, SETTLE = 300.0, 180.0 RETRY, SETTLE = 300.0, 180.0
+1 -1
View File
@@ -5,7 +5,7 @@ import uuid
import pytest import pytest
from nisse_core.execution import SSHHost from nisse_core.execution.ssh import SSHHost
from nisse_dev.loop import preflight from nisse_dev.loop import preflight
from nisse_dev.loop.preflight import Tool from nisse_dev.loop.preflight import Tool
+1 -1
View File
@@ -4,7 +4,7 @@ from pathlib import Path
import pytest import pytest
from nisse_core.execution import REDACTED, SSHHost from nisse_core.execution.ssh import REDACTED, SSHHost
from nisse_dev.tools import EXECUTION_TOOLS, MAX_OUTPUT_CHARS, Workspace from nisse_dev.tools import EXECUTION_TOOLS, MAX_OUTPUT_CHARS, Workspace
+1 -1
View File
@@ -14,8 +14,8 @@ import os
import sys import sys
from pathlib import Path from pathlib import Path
from nisse_core.catalog import ModelCatalog
from nisse_core.envfile import load_env_file from nisse_core.envfile import load_env_file
from nisse_core.models.catalog import ModelCatalog
from nisse_dev.bench.results import append, load, render, results_file, summarise from nisse_dev.bench.results import append, load, render, results_file, summarise
from nisse_dev.bench.runner import agent_commit, run_task from nisse_dev.bench.runner import agent_commit, run_task
from nisse_dev.bench.tasks import load_tasks from nisse_dev.bench.tasks import load_tasks
+1 -1
View File
@@ -133,7 +133,7 @@ cmd_logs() { journalctl -u "$UNIT" -f -o cat; }
# The state store, read with the image's own code. # The state store, read with the image's own code.
dump() { dump() {
docker run --rm --user 0 -v "$E2E:$E2E" --entrypoint python "$IMAGE" \ docker run --rm --user 0 -v "$E2E:$E2E" --entrypoint python "$IMAGE" \
-m nisse_core.dump "$@" -m nisse_core.state.dump "$@"
} }
cmd_collect() { cmd_collect() {
Loaded 100 of 117 files, more files were not shown because too many files have changed in this diff. Show more