@inneranimalmedia/agentsam-sdk 2.6.0 → 2.6.2
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.
- package/docs/AUTH_IDENTITY_CONTRACT.md +25 -27
- package/docs/PLATFORM_RUNTIME_EVENTS.md +48 -0
- package/docs/RELEASES.md +7 -7
- package/docs/SDK_WORKER.md +4 -3
- package/docs/SOURCE_ARCHITECTURE.md +58 -0
- package/docs/TEST_TIERS.md +26 -0
- package/migrations/runtime/0001_cli_runtime.sql +298 -0
- package/package.json +28 -7
- package/packages/agentsam-repository/README.md +15 -0
- package/packages/agentsam-repository/package.json +25 -0
- package/packages/agentsam-repository/src/contracts.js +113 -0
- package/packages/agentsam-repository/src/index.js +3 -0
- package/{src/lib → packages/agentsam-repository/src}/merkle/cloudflare-persistence.js +14 -24
- package/{src/lib → packages/agentsam-repository/src}/merkle/index.js +1 -0
- package/{src/lib → packages/agentsam-repository/src}/merkle/persistence.js +6 -4
- package/{src/lib → packages/agentsam-repository/src}/merkle/policy.js +1 -0
- package/packages/agentsam-repository/test/contracts.test.mjs +40 -0
- package/packages/agentsam-repository/test/git-context.test.mjs +24 -0
- package/{test/merkle.test.mjs → packages/agentsam-repository/test/merkle-core.test.mjs} +2 -32
- package/{test → packages/agentsam-repository/test}/merkle-persistence.test.mjs +11 -6
- package/packages/identity/package.json +2 -2
- package/packages/identity/src/contracts/auth-config.js +23 -40
- package/packages/identity/tests/auth-config.test.mjs +14 -23
- package/protocol/COMPANY_REPOSITORY_GRAPH_V1.md +91 -0
- package/protocol/MERKLE_PERSISTENCE_V1.md +2 -0
- package/protocol/MERKLE_PERSISTENCE_V2.md +40 -0
- package/protocol/repository/repository-contract.schema.json +24 -0
- package/protocol/repository/repository-dependency.schema.json +24 -0
- package/protocol/repository/repository-identity.schema.json +17 -0
- package/protocol/rpc/v1/common.proto +16 -0
- package/protocol/rpc/v1/errors.proto +35 -0
- package/protocol/rpc/v1/knowledge.proto +77 -0
- package/services/knowledge/package-lock.json +333 -0
- package/services/knowledge/package.json +5 -1
- package/src/agent/responses-runner.js +63 -35
- package/src/capabilities/repository-snapshot.js +3 -3
- package/src/cli.js +36 -29
- package/src/commands/account-auth.js +1 -1
- package/src/commands/context-economics.js +17 -2
- package/src/commands/context.js +1 -1
- package/src/commands/db.js +20 -3
- package/src/commands/deploy.js +2 -2
- package/src/commands/env.js +90 -0
- package/src/commands/knowledge.js +12 -4
- package/src/commands/merkle-persist.js +30 -11
- package/src/commands/merkle.js +1 -1
- package/src/commands/models.js +123 -65
- package/src/commands/ollama.js +26 -0
- package/src/commands/preferences.js +53 -26
- package/src/commands/providers.js +308 -0
- package/src/commands/shell.js +240 -48
- package/src/commands/tunnel.js +8 -8
- package/src/commands/whoami.js +42 -21
- package/src/errors/contract.js +236 -0
- package/src/errors/diagnostic.js +1 -0
- package/src/errors/index.js +14 -0
- package/src/index.js +13 -1
- package/src/knowledge/service/auth.js +13 -0
- package/src/knowledge/service/grpc-client.js +115 -0
- package/src/knowledge/service/grpc-codec.js +237 -0
- package/src/knowledge/service/grpc-server.js +83 -0
- package/src/knowledge/service/job-engine.js +248 -0
- package/src/knowledge/service/server.js +87 -135
- package/src/knowledge/source.js +1 -1
- package/src/lib/account-session.js +94 -25
- package/src/lib/auth.js +314 -51
- package/src/lib/cli-preferences.js +31 -4
- package/src/lib/core-client.js +75 -30
- package/src/lib/deploy-receipt/index.js +2 -2
- package/src/lib/detect-context.js +14 -16
- package/src/lib/knowledge-docker.js +6 -3
- package/src/lib/local-sessions.js +23 -2
- package/src/lib/local-status.js +1 -1
- package/src/lib/project-config.js +1 -1
- package/src/lib/provider-credentials.js +230 -14
- package/src/lib/slash-commands.js +5 -3
- package/src/local/migrations.js +93 -0
- package/src/local/runtime-store.js +141 -0
- package/src/local/sqlite.js +2 -0
- package/src/local-pty/server.js +113 -51
- package/src/models/discovery.js +327 -0
- package/src/providers/anthropic-messages.js +192 -0
- package/src/providers/cloudflare-chat.js +183 -0
- package/src/providers/factory.js +69 -0
- package/src/providers/gemini-generate-content.js +208 -0
- package/src/providers/index.js +5 -0
- package/src/providers/ollama-chat.js +148 -0
- package/src/providers/openai-responses.js +226 -75
- package/src/repository/index.js +14 -2
- package/src/rpc/generated/common_grpc_pb.js +1 -0
- package/src/rpc/generated/common_pb.js +536 -0
- package/src/rpc/generated/errors_grpc_pb.js +1 -0
- package/src/rpc/generated/errors_pb.js +482 -0
- package/src/rpc/generated/knowledge_grpc_pb.js +135 -0
- package/src/rpc/generated/knowledge_pb.js +2168 -0
- package/src/rpc/generated/package.json +3 -0
- package/src/security/trust-boundary.js +2 -2
- package/src/telemetry/events.js +4 -1
- package/src/ui/cli/activity.js +76 -0
- package/src/ui/cli/compaction.js +15 -0
- package/src/ui/cli/footer.js +39 -0
- package/src/ui/cli/help.js +194 -0
- package/src/ui/cli/plan.js +20 -0
- package/src/ui/cli/runtime-events.js +110 -0
- package/src/ui/cli/waiting.js +16 -0
- package/src/ui/merkle/render.js +1 -1
- package/test/account-session.test.mjs +48 -11
- package/test/apps-scaffold-contract.test.mjs +43 -0
- package/test/cli/preferences-runtime.test.mjs +11 -0
- package/test/cli/runtime-ui.test.mjs +74 -0
- package/test/error-diagnostics.test.mjs +57 -1
- package/test/fixtures/knowledge-rpc-worker.mjs +16 -0
- package/test/integration/cli-help.test.mjs +37 -0
- package/test/integration/knowledge-rpc.test.mjs +112 -0
- package/test/integration/merkle-cli.test.mjs +61 -0
- package/test/integration/merkle-persistence-identity.test.mjs +48 -0
- package/test/integration/provider-env-cli.test.mjs +49 -0
- package/test/integration/provider-factory.test.mjs +197 -0
- package/test/integration/repository-company-graph.test.mjs +90 -0
- package/test/integration/runtime-migrations.test.mjs +82 -0
- package/test/knowledge-service.test.mjs +5 -0
- package/test/knowledge.test.mjs +16 -0
- package/test/live/terminal-transport.live.test.mjs +24 -0
- package/test/local-sessions.test.mjs +7 -1
- package/test/models.test.mjs +101 -4
- package/test/ollama.test.mjs +21 -0
- package/test/portable-context.test.mjs +1 -1
- package/test/provider-credentials.test.mjs +45 -1
- package/test/release-hygiene.test.mjs +13 -5
- package/test/responses-runner.test.mjs +3 -1
- package/test/sdk-worker-contract.test.mjs +5 -1
- package/test/shell.test.mjs +50 -8
- package/test/smoke.mjs +2 -1
- package/test/terminal/local-pty.mock.test.mjs +151 -0
- package/test/whoami-resume.test.mjs +6 -5
- package/src/lib/prompt-byok.js +0 -57
- package/src/lib/save-sdk-token.js +0 -19
- /package/{src/lib → packages/agentsam-repository/src}/git-context.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/diff.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/filemeta.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/git-ignore.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/hash.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/semantic.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/snapshot.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/tree.js +0 -0
|
@@ -6,47 +6,45 @@ The `agentsam-sdk` package owns the portable public configuration contract. Cons
|
|
|
6
6
|
|
|
7
7
|
| Variable | Meaning |
|
|
8
8
|
| --- | --- |
|
|
9
|
-
| `
|
|
9
|
+
| `IAM_OAUTH_ISSUER` | Canonical IAM authority/issuer for browser OAuth and platform account requests. |
|
|
10
|
+
| `IAM_ORIGIN` | Migration fallback for the IAM issuer. New code resolves `IAM_OAUTH_ISSUER` first. |
|
|
10
11
|
| `IAM_CLIENT_ID` | OAuth client id for an application using IAM identity. |
|
|
11
12
|
| `IAM_CLIENT_SECRET` | OAuth client secret. Keep it server-side. |
|
|
12
|
-
| `
|
|
13
|
-
| `AGENTSAM_BRIDGE_KEY` |
|
|
13
|
+
| `AGENTSAM_API_KEY` | Reusable account/delegated API credential. Raw values use the `aak_` prefix and are sent as `Authorization: Bearer …`. |
|
|
14
|
+
| `AGENTSAM_BRIDGE_KEY` | Infrastructure/machine integration trust. It is never a substitute for account authentication. |
|
|
14
15
|
|
|
15
|
-
The host-side durable verifier for
|
|
16
|
+
The host-side durable verifier for reusable AgentSam API credentials is `agentsam_api_credentials`. The SDK defines the public credential semantics; the host owns credential issuance, hashing, storage, revocation, and authorization.
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
Interactive browser login is intentionally separate from `AGENTSAM_API_KEY`. The CLI stores an opaque machine-local browser session under `~/.agentsam/auth/session.json`; it does not turn that session into a reusable API key.
|
|
18
19
|
|
|
19
20
|
## Migration compatibility
|
|
20
21
|
|
|
21
|
-
The
|
|
22
|
+
The issuer resolver accepts `IAM_ORIGIN` only when `IAM_OAUTH_ISSUER` is absent. The retired `AGENTSAM_SDK_KEY`, `AGENTSAM_SDK_TOKEN`, `sdk_` bearer, and `agentsam_sdk_tokens` account-auth contract is not read by the current SDK.
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
IAM_ORIGIN
|
|
25
|
-
fallback: IAM_OAUTH_ISSUER
|
|
26
|
-
|
|
27
|
-
AGENTSAM_SDK_KEY
|
|
28
|
-
fallback: AGENTSAM_SDK_TOKEN
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Canonical names always win when both are present. New scaffolds, docs, and writes emit only the canonical names. Compatibility aliases are intentionally not a permanent parallel configuration surface.
|
|
32
|
-
|
|
33
|
-
Older platform-base aliases (`IAM_CORE_URL`, `AGENTSAM_CORE_URL`, `AGENTSAM_BASE_URL`) are compatibility-only. SDK clients prefer `IAM_ORIGIN`.
|
|
24
|
+
Older platform-base aliases (`IAM_CORE_URL`, `AGENTSAM_CORE_URL`, `AGENTSAM_BASE_URL`) remain compatibility-only where legacy clients still consume them.
|
|
34
25
|
|
|
35
26
|
## Credential boundaries
|
|
36
27
|
|
|
37
28
|
```text
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
->
|
|
41
|
-
-> Authorization: Bearer <
|
|
29
|
+
reusable account API lane
|
|
30
|
+
AGENTSAM_API_KEY
|
|
31
|
+
-> aak_* bearer
|
|
32
|
+
-> Authorization: Bearer <aak_*>
|
|
42
33
|
-> account/delegated authority
|
|
43
|
-
->
|
|
34
|
+
-> agentsam_api_credentials (hashed verifier on the host)
|
|
35
|
+
|
|
36
|
+
interactive browser lane
|
|
37
|
+
agentsam login
|
|
38
|
+
-> opaque browser session credential
|
|
39
|
+
-> ~/.agentsam/auth/session.json
|
|
40
|
+
-> interactive account authority
|
|
41
|
+
-> never rewritten as AGENTSAM_API_KEY
|
|
44
42
|
|
|
45
|
-
machine/
|
|
46
|
-
|
|
43
|
+
machine/infrastructure lane
|
|
44
|
+
enrolled opaque machine credential / infrastructure bridge trust
|
|
47
45
|
-> machine principal
|
|
48
|
-
->
|
|
49
|
-
->
|
|
46
|
+
-> server resolves connection -> instance -> account
|
|
47
|
+
-> never accepted as account API auth
|
|
50
48
|
```
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
Repository identity, workspace labels, terminal instance ids, and machine trust do not prove reusable account authority. Provider credentials such as `OPENAI_API_KEY`, `GEMINI_API_KEY`, `CURSOR_API_KEY`, and Cloudflare credentials are managed separately by the machine provider-credential service.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Platform runtime event dependency
|
|
2
|
+
|
|
3
|
+
Status: **SDK consumer ready; platform producer pending.**
|
|
4
|
+
|
|
5
|
+
The standalone CLI does not depend on a platform event endpoint. Local/provider execution emits runtime events directly into the same presenter used by future platform-connected sessions.
|
|
6
|
+
|
|
7
|
+
The cross-repo dependency is in `SamPrimeaux/inneranimalmedia`: its pending agent-runtime SSE/event channel must eventually deliver the same normalized envelope consumed by:
|
|
8
|
+
|
|
9
|
+
`src/ui/cli/runtime-events.js -> normalizeRuntimeEventEnvelope()`
|
|
10
|
+
|
|
11
|
+
The SDK intentionally does **not** invent a route such as `/api/sdk/agent/runs`. Endpoint ownership, authorization, reconnection, and SSE lifecycle belong to the platform repository.
|
|
12
|
+
|
|
13
|
+
## Producer contract
|
|
14
|
+
|
|
15
|
+
Each platform event delivered to the SDK must normalize to:
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
{
|
|
19
|
+
schema_version: 1,
|
|
20
|
+
type: "tool.started",
|
|
21
|
+
timestamp: "2026-09-18T00:00:00.000Z",
|
|
22
|
+
run_id: "run_...",
|
|
23
|
+
sequence: 3,
|
|
24
|
+
payload: {
|
|
25
|
+
// event-specific data
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`run_id` and `sequence` are optional when the source cannot supply them. `type` is required. `payload` is always normalized to an object.
|
|
31
|
+
|
|
32
|
+
The SDK adds the internal contract marker `schema: "agentsam-runtime-event-v1"` after normalization. Platform producers do not need to know about CLI rendering, spinners, plans, approval prompts, compaction UI, or footer layout. They only emit the envelope.
|
|
33
|
+
|
|
34
|
+
Current event vocabulary is declared in `src/telemetry/events.js`, including model, usage, cost, context, tool, approval, plan/task, timer, waiting-input, error, and run lifecycle events.
|
|
35
|
+
|
|
36
|
+
## Boundary
|
|
37
|
+
|
|
38
|
+
Standalone completion is not blocked by this dependency.
|
|
39
|
+
|
|
40
|
+
The release-blocking standalone path is:
|
|
41
|
+
|
|
42
|
+
provider/local runtime -> AgentEvent -> normalizeRuntimeEventEnvelope -> CLI presenter
|
|
43
|
+
|
|
44
|
+
The later platform-connected path should be:
|
|
45
|
+
|
|
46
|
+
platform runtime -> SSE/WebSocket transport -> normalizeRuntimeEventEnvelope -> same CLI presenter
|
|
47
|
+
|
|
48
|
+
If platform integration requires changing the presenter contract instead of only adding the transport connection, treat that as a contract regression.
|
package/docs/RELEASES.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# `@inneranimalmedia/agentsam-sdk` release receipts
|
|
2
2
|
|
|
3
|
-
**2.6.0 is
|
|
4
|
-
The npm `latest` dist-tag is **2.5.0**. The private identity workspace continues to
|
|
3
|
+
**2.6.0 is published and is the npm `latest` release.** The private identity workspace continues to
|
|
5
4
|
ship through root SDK exports and is not published separately.
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
`
|
|
6
|
+
Published at `2026-09-12T21:14:57.827Z` from git SHA
|
|
7
|
+
`ae32fba0a761cb18c5f940957bdcd58e3cab6072`, tagged `v2.6.0`. Registry integrity:
|
|
8
|
+
`sha512-98xvyIXGcX6/S0nFUkB2+s4zPxF5WvN/eYBjt6s575uC/ux/xB9Y0dH+pw7ur5TMRkQj7JDR4XN5cSy6I2Hr+w==`.
|
|
9
|
+
Publishing remains manual and `prepublishOnly` runs `npm run verify:release`.
|
|
10
10
|
|
|
11
|
-
## 2.6.0
|
|
11
|
+
## 2.6.0 highlights
|
|
12
12
|
|
|
13
13
|
- Interactive AgentSam now has persistent machine-local account/session identity with explicit `login`, `logout`, `whoami`, and `resume` flows.
|
|
14
14
|
- `/models` and model-selection UX bind to the canonical model inventory v2 contract instead of maintaining a second CLI catalog.
|
|
@@ -31,7 +31,7 @@ here after release. Publishing remains manual and `prepublishOnly` runs
|
|
|
31
31
|
|
|
32
32
|
| npm version | Published (UTC) | IAM git SHA (40) | Notes |
|
|
33
33
|
|-------------|-----------------|------------------|-------|
|
|
34
|
-
| 2.6.0 |
|
|
34
|
+
| 2.6.0 | 2026-09-12T21:14:57.827Z | `ae32fba0a761cb18c5f940957bdcd58e3cab6072` | Published package; npm `latest`; registry `gitHead`, shasum, integrity, and `v2.6.0` tag verified. |
|
|
35
35
|
| 2.5.0 | 2026-09-11T21:27:11.516Z | `da28623dc4808025b77605ed09aa16217b1db607` | Published package; registry `gitHead` receipt. |
|
|
36
36
|
| 2.4.1 | 2026-09-11T05:45:03.622Z | `a256ababededd904da555e7898bc8afd753737d2` | Latest published package before 2.5.0. |
|
|
37
37
|
| 2.4.0 | 2026-09-11T05:29:02.811Z | `81c8659977953bed53c2adb0a341ce7382be4794` | Published 2.4 line. |
|
package/docs/SDK_WORKER.md
CHANGED
|
@@ -47,16 +47,17 @@ agentsam-sdk
|
|
|
47
47
|
├─ AGENTSAM_WAI -> Workers AI provider
|
|
48
48
|
├─ EXECOS -> execos service binding
|
|
49
49
|
├─ PTY_SERVICE -> iam-vpc VPC service
|
|
50
|
-
├─
|
|
50
|
+
├─ IAM_OAUTH_ISSUER -> https://inneranimalmedia.com
|
|
51
|
+
├─ IAM_ORIGIN -> migration fallback
|
|
51
52
|
├─ IAM_CLIENT_ID -> public OAuth client id
|
|
52
53
|
├─ IAM_CLIENT_SECRET -> secret
|
|
53
|
-
├─
|
|
54
|
+
├─ AGENTSAM_API_KEY -> aak_ account credential (only when a reusable account credential is needed)
|
|
54
55
|
└─ AGENTSAM_BRIDGE_KEY -> secret
|
|
55
56
|
```
|
|
56
57
|
|
|
57
58
|
Hosted model credentials are secrets: `XAI_API_KEY`, `OPENAI_API_KEY`, and `GEMINI_API_KEY`. Grok model inference is the `XAI_API_KEY` provider lane and is independent from the pre-wired Grok gate viewer identity/session system.
|
|
58
59
|
|
|
59
|
-
`AGENTSAM_WORKER_ROLE` is not part of the SDK contract. `IAM_OAUTH_ISSUER`
|
|
60
|
+
`AGENTSAM_WORKER_ROLE` is not part of the SDK contract. `IAM_OAUTH_ISSUER` is the canonical IAM authority; `IAM_ORIGIN` is a migration fallback. Reusable account API credentials use `AGENTSAM_API_KEY` with an `aak_` prefix. Browser login sessions and machine/infrastructure credentials remain separate and must not be promoted into account API keys.
|
|
60
61
|
|
|
61
62
|
## Ollama
|
|
62
63
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# AgentSam SDK source architecture
|
|
2
|
+
|
|
3
|
+
The SDK root is the product/package composition layer, not the permanent home for every reusable subsystem.
|
|
4
|
+
|
|
5
|
+
## Ownership rule
|
|
6
|
+
|
|
7
|
+
New reusable code should have an explicit owner:
|
|
8
|
+
|
|
9
|
+
- `packages/agentsam-contracts/` — framework-neutral wire/types vocabulary shared across AgentSam products and repositories.
|
|
10
|
+
- `packages/identity/` — identity/auth contracts and adapters.
|
|
11
|
+
- `packages/connectors/*/` — provider-specific connectors.
|
|
12
|
+
- `packages/agentsam-workbench/` — reusable UI/workbench primitives.
|
|
13
|
+
- `apps/*/` — self-contained applications with their own frontend/backend/shared package boundaries.
|
|
14
|
+
- root `src/commands/`, `src/cli.js`, and `src/index.js` — SDK/CLI composition and public facade.
|
|
15
|
+
|
|
16
|
+
`src/lib/` is a legacy extraction zone. Its current files are supported, but new unrelated reusable modules must not be added there. The source-boundary verifier freezes that surface so it can shrink over time.
|
|
17
|
+
|
|
18
|
+
## Package extraction status
|
|
19
|
+
|
|
20
|
+
Do not split the repo into micro-packages for their own sake. Extract a subsystem when it has a coherent public responsibility and can own its tests.
|
|
21
|
+
|
|
22
|
+
**Extracted:** `packages/agentsam-repository/` now owns Git identity, Merkle/filemeta algorithms, repository graph runtime normalization, and snapshot persistence. Root SDK exports and CLI/runtime consumers compose that package without restoring `src/lib/merkle` or `src/lib/git-context.js`.
|
|
23
|
+
|
|
24
|
+
Next coherent extractions:
|
|
25
|
+
|
|
26
|
+
1. **Runtime/core** — account session, provider credentials, execution approvals, run/session primitives, and telemetry composition that are not CLI-specific.
|
|
27
|
+
2. **Knowledge/indexing** — repository knowledge engine, stores, indexing provider contracts, and service client/runtime seams.
|
|
28
|
+
|
|
29
|
+
The root CLI should depend on these packages; packages must not depend on root CLI/commands/UI internals.
|
|
30
|
+
|
|
31
|
+
## Test placement
|
|
32
|
+
|
|
33
|
+
Package behavior belongs with the package:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
packages/identity/tests/*
|
|
37
|
+
packages/agentsam-contracts/test/*
|
|
38
|
+
packages/agentsam-workbench/test/*
|
|
39
|
+
packages/connectors/cloudflare/tests/*
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Root SDK tests should move toward explicit roles:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
test/integration/* cross-package/root-facade behavior
|
|
46
|
+
test/cli/* CLI command behavior
|
|
47
|
+
test/release/* packaging/release hygiene
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The existing flat `test/*.test.mjs` set is legacy debt. It is frozen: old tests may remain while their owning subsystem is extracted, but new flat tests are rejected by `npm run verify:boundaries`.
|
|
51
|
+
|
|
52
|
+
## App isolation
|
|
53
|
+
|
|
54
|
+
Every `apps/<name>/` is a self-contained application boundary. Apps may consume documented SDK/package exports, but must not deep-import root `src/` implementation files. Reusable app logic should live in that app's `shared/` package first, then move to a top-level package only when it is genuinely cross-application.
|
|
55
|
+
|
|
56
|
+
## Company graph / Merkle authority
|
|
57
|
+
|
|
58
|
+
`agentsam-sdk` defines the portable vocabulary and deterministic algorithms. `inneranimalmedia` owns account-scoped operational persistence. The SDK must not introduce tenant/workspace/user ownership aliases or environment variables that impersonate authenticated account/repository authority.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# AgentSam SDK test tiers
|
|
2
|
+
|
|
3
|
+
The release-blocking test gate must be deterministic and must not require ExecOS, a user-hosted terminal tunnel, a cloud VM, or any other live external daemon.
|
|
4
|
+
|
|
5
|
+
## Release-blocking tiers
|
|
6
|
+
|
|
7
|
+
`npm test` runs these tiers:
|
|
8
|
+
|
|
9
|
+
- `npm run test:unit` — deterministic unit/contract tests.
|
|
10
|
+
- `npm run test:integration:mock` — integration behavior against local or mocked dependencies.
|
|
11
|
+
- `npm run test:terminal:mock` — terminal/PTY behavior through an injected mock PTY transport. No ExecOS or tunnel is contacted.
|
|
12
|
+
- identity and connector tests already included by the root `npm test` script.
|
|
13
|
+
|
|
14
|
+
These tiers are the standard release gate and are suitable for GitHub Actions.
|
|
15
|
+
|
|
16
|
+
## Live terminal tier
|
|
17
|
+
|
|
18
|
+
`npm run test:live:terminal` is deliberately outside `npm test` and `npm run verify`.
|
|
19
|
+
|
|
20
|
+
Set `AGENTSAM_LIVE_TERMINAL_WS_URL` to a real enrolled terminal WebSocket URL when an operator intentionally wants to exercise a live transport. `AGENTSAM_LIVE_TERMINAL_AUTH` may be supplied when that endpoint requires an Authorization header.
|
|
21
|
+
|
|
22
|
+
If no live URL is supplied, the live test is skipped. A tunnel outage must never make the package release gate red.
|
|
23
|
+
|
|
24
|
+
## Rule
|
|
25
|
+
|
|
26
|
+
Tests may verify terminal protocol semantics in the release-blocking suite only through a local/mock transport. Any test that depends on ExecOS, a provisioned IAM terminal connection, Cloudflare Tunnel, or a real remote PTY belongs in the explicit live tier.
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
-- AgentSam portable CLI/runtime state.
|
|
2
|
+
-- Compatible with Node SQLite and Cloudflare D1.
|
|
3
|
+
-- Identity is account_id when available; standalone installs may leave account_id NULL.
|
|
4
|
+
-- Derived from live IAM runtime tables on 2026-09-17, with tenant/workspace fields intentionally removed.
|
|
5
|
+
|
|
6
|
+
PRAGMA foreign_keys = ON;
|
|
7
|
+
|
|
8
|
+
CREATE TABLE IF NOT EXISTS agentsam_agent_run (
|
|
9
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
10
|
+
account_id TEXT,
|
|
11
|
+
conversation_id TEXT,
|
|
12
|
+
external_agent_id TEXT,
|
|
13
|
+
external_run_id TEXT,
|
|
14
|
+
parent_run_id TEXT REFERENCES agentsam_agent_run(id) ON DELETE SET NULL,
|
|
15
|
+
source_client TEXT,
|
|
16
|
+
surface TEXT,
|
|
17
|
+
mode TEXT NOT NULL DEFAULT 'agent'
|
|
18
|
+
CHECK (mode IN ('ask','plan','agent','debug','multitask')),
|
|
19
|
+
model_key TEXT,
|
|
20
|
+
reasoning_effort TEXT,
|
|
21
|
+
requested_service_tier TEXT,
|
|
22
|
+
actual_service_tier TEXT,
|
|
23
|
+
selected_by TEXT CHECK (selected_by IS NULL OR selected_by IN ('manual','automatic','fallback')),
|
|
24
|
+
status TEXT NOT NULL DEFAULT 'queued'
|
|
25
|
+
CHECK (status IN ('queued','running','paused','completed','failed','partial','cancelled')),
|
|
26
|
+
cancel_requested INTEGER NOT NULL DEFAULT 0 CHECK (cancel_requested IN (0,1)),
|
|
27
|
+
error_code TEXT,
|
|
28
|
+
error_message TEXT,
|
|
29
|
+
model_call_count INTEGER NOT NULL DEFAULT 0 CHECK (model_call_count >= 0),
|
|
30
|
+
tool_call_count INTEGER NOT NULL DEFAULT 0 CHECK (tool_call_count >= 0),
|
|
31
|
+
input_tokens INTEGER NOT NULL DEFAULT 0 CHECK (input_tokens >= 0),
|
|
32
|
+
cached_input_tokens INTEGER NOT NULL DEFAULT 0 CHECK (cached_input_tokens >= 0),
|
|
33
|
+
output_tokens INTEGER NOT NULL DEFAULT 0 CHECK (output_tokens >= 0),
|
|
34
|
+
reasoning_tokens INTEGER NOT NULL DEFAULT 0 CHECK (reasoning_tokens >= 0),
|
|
35
|
+
cost_usd REAL NOT NULL DEFAULT 0 CHECK (cost_usd >= 0),
|
|
36
|
+
created_at_unix INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
37
|
+
started_at_unix INTEGER,
|
|
38
|
+
completed_at_unix INTEGER,
|
|
39
|
+
updated_at_unix INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
40
|
+
latency_ms INTEGER
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
CREATE INDEX IF NOT EXISTS idx_agentsam_agent_run_account_updated
|
|
44
|
+
ON agentsam_agent_run(account_id, updated_at_unix DESC);
|
|
45
|
+
CREATE INDEX IF NOT EXISTS idx_agentsam_agent_run_parent
|
|
46
|
+
ON agentsam_agent_run(parent_run_id, created_at_unix);
|
|
47
|
+
|
|
48
|
+
CREATE TABLE IF NOT EXISTS agentsam_compaction_events (
|
|
49
|
+
id TEXT PRIMARY KEY DEFAULT ('cmp_' || lower(hex(randomblob(8)))),
|
|
50
|
+
account_id TEXT,
|
|
51
|
+
agent_run_id TEXT REFERENCES agentsam_agent_run(id) ON DELETE SET NULL,
|
|
52
|
+
conversation_id TEXT,
|
|
53
|
+
compaction_type TEXT NOT NULL DEFAULT 'context_summary'
|
|
54
|
+
CHECK (compaction_type IN (
|
|
55
|
+
'context_summary','data_summary','run_summary','usage_summary',
|
|
56
|
+
'memory_summary','rule_summary','audit_summary','performance_summary','routing_summary'
|
|
57
|
+
)),
|
|
58
|
+
compaction_scope TEXT NOT NULL DEFAULT 'agent_run'
|
|
59
|
+
CHECK (compaction_scope IN ('rowset','table','agent_run','workflow','system')),
|
|
60
|
+
compaction_strategy TEXT NOT NULL DEFAULT 'summarize'
|
|
61
|
+
CHECK (compaction_strategy IN ('summarize','truncate','selective','full','rollup','audit')),
|
|
62
|
+
source_kind TEXT NOT NULL DEFAULT 'api'
|
|
63
|
+
CHECK (source_kind IN (
|
|
64
|
+
'd1','sqlite','r2','supabase','vectorize','hyperdrive','github',
|
|
65
|
+
'filesystem','worker_logs','api','browser','screenshot','mixed'
|
|
66
|
+
)),
|
|
67
|
+
source_table TEXT NOT NULL DEFAULT '',
|
|
68
|
+
source_row_count INTEGER NOT NULL DEFAULT 0,
|
|
69
|
+
source_min_epoch INTEGER,
|
|
70
|
+
source_max_epoch INTEGER,
|
|
71
|
+
source_filter_json TEXT NOT NULL DEFAULT '{}',
|
|
72
|
+
source_snapshot_json TEXT NOT NULL DEFAULT '{}',
|
|
73
|
+
source_query_hash TEXT NOT NULL DEFAULT '',
|
|
74
|
+
content_hash TEXT NOT NULL DEFAULT '',
|
|
75
|
+
provider TEXT NOT NULL DEFAULT '',
|
|
76
|
+
model_key TEXT NOT NULL DEFAULT '',
|
|
77
|
+
tokens_before INTEGER NOT NULL DEFAULT 0,
|
|
78
|
+
tokens_after INTEGER NOT NULL DEFAULT 0,
|
|
79
|
+
tokens_saved INTEGER GENERATED ALWAYS AS (tokens_before - tokens_after) STORED,
|
|
80
|
+
cost_before_usd REAL NOT NULL DEFAULT 0,
|
|
81
|
+
cost_after_usd REAL NOT NULL DEFAULT 0,
|
|
82
|
+
cost_saved_usd REAL GENERATED ALWAYS AS (cost_before_usd - cost_after_usd) STORED,
|
|
83
|
+
status TEXT NOT NULL DEFAULT 'completed'
|
|
84
|
+
CHECK(status IN ('queued','running','completed','failed','cancelled','needs_review')),
|
|
85
|
+
summary_text TEXT NOT NULL DEFAULT '',
|
|
86
|
+
summary_json TEXT NOT NULL DEFAULT '{}',
|
|
87
|
+
metrics_json TEXT NOT NULL DEFAULT '{}',
|
|
88
|
+
findings_json TEXT NOT NULL DEFAULT '{}',
|
|
89
|
+
recommended_actions_json TEXT NOT NULL DEFAULT '[]',
|
|
90
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
91
|
+
source_stored TEXT NOT NULL DEFAULT 'local:agentsam_compaction_events',
|
|
92
|
+
source_url TEXT NOT NULL DEFAULT '',
|
|
93
|
+
report_artifact_url TEXT NOT NULL DEFAULT '',
|
|
94
|
+
expires_at_epoch INTEGER,
|
|
95
|
+
compacted_at_epoch INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
96
|
+
created_at_epoch INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
97
|
+
updated_at_epoch INTEGER NOT NULL DEFAULT (unixepoch())
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
CREATE INDEX IF NOT EXISTS idx_agentsam_compaction_run
|
|
101
|
+
ON agentsam_compaction_events(agent_run_id, compacted_at_epoch DESC);
|
|
102
|
+
CREATE INDEX IF NOT EXISTS idx_agentsam_compaction_expiry
|
|
103
|
+
ON agentsam_compaction_events(expires_at_epoch)
|
|
104
|
+
WHERE expires_at_epoch IS NOT NULL;
|
|
105
|
+
|
|
106
|
+
CREATE TABLE IF NOT EXISTS agentsam_context_digest (
|
|
107
|
+
id TEXT PRIMARY KEY,
|
|
108
|
+
account_id TEXT,
|
|
109
|
+
digest_type TEXT NOT NULL CHECK (
|
|
110
|
+
digest_type IN (
|
|
111
|
+
'schema','repo','docs','memory','tool_registry','route_map',
|
|
112
|
+
'session','deployment','rag','conversation','handoff','project'
|
|
113
|
+
)
|
|
114
|
+
),
|
|
115
|
+
project_id TEXT,
|
|
116
|
+
agent_run_id TEXT REFERENCES agentsam_agent_run(id) ON DELETE SET NULL,
|
|
117
|
+
session_id TEXT,
|
|
118
|
+
source_hash TEXT NOT NULL,
|
|
119
|
+
digest_hash TEXT NOT NULL UNIQUE,
|
|
120
|
+
raw_size_bytes INTEGER,
|
|
121
|
+
reduced_size_bytes INTEGER,
|
|
122
|
+
token_count INTEGER,
|
|
123
|
+
digest_text TEXT NOT NULL,
|
|
124
|
+
generation_model TEXT,
|
|
125
|
+
namespace TEXT,
|
|
126
|
+
hit_count INTEGER NOT NULL DEFAULT 0,
|
|
127
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
128
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
129
|
+
created_at_unix INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
130
|
+
source_updated_at_unix INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
131
|
+
updated_at_unix INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
132
|
+
expires_at_unix INTEGER,
|
|
133
|
+
embedding_model TEXT,
|
|
134
|
+
embedding_dimensions INTEGER,
|
|
135
|
+
compaction_event_id TEXT
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
CREATE INDEX IF NOT EXISTS idx_agentsam_context_digest_session
|
|
139
|
+
ON agentsam_context_digest(session_id, source_updated_at_unix DESC)
|
|
140
|
+
WHERE session_id IS NOT NULL;
|
|
141
|
+
CREATE INDEX IF NOT EXISTS idx_agentsam_context_digest_run
|
|
142
|
+
ON agentsam_context_digest(agent_run_id, source_updated_at_unix DESC)
|
|
143
|
+
WHERE agent_run_id IS NOT NULL;
|
|
144
|
+
CREATE INDEX IF NOT EXISTS idx_agentsam_context_digest_compaction
|
|
145
|
+
ON agentsam_context_digest(compaction_event_id)
|
|
146
|
+
WHERE compaction_event_id IS NOT NULL;
|
|
147
|
+
|
|
148
|
+
CREATE TRIGGER IF NOT EXISTS context_digest_set_initial_expiry
|
|
149
|
+
AFTER INSERT ON agentsam_context_digest
|
|
150
|
+
WHEN NEW.expires_at_unix IS NULL
|
|
151
|
+
BEGIN
|
|
152
|
+
UPDATE agentsam_context_digest
|
|
153
|
+
SET expires_at_unix = CASE
|
|
154
|
+
WHEN NEW.digest_type IN ('session','conversation','handoff')
|
|
155
|
+
THEN unixepoch() + 2592000
|
|
156
|
+
ELSE NULL
|
|
157
|
+
END
|
|
158
|
+
WHERE id = NEW.id;
|
|
159
|
+
END;
|
|
160
|
+
|
|
161
|
+
CREATE TRIGGER IF NOT EXISTS context_digest_extend_on_hit
|
|
162
|
+
AFTER UPDATE OF hit_count ON agentsam_context_digest
|
|
163
|
+
WHEN NEW.hit_count > OLD.hit_count AND OLD.expires_at_unix IS NOT NULL
|
|
164
|
+
BEGIN
|
|
165
|
+
UPDATE agentsam_context_digest
|
|
166
|
+
SET expires_at_unix = unixepoch() + 2592000,
|
|
167
|
+
updated_at_unix = unixepoch(),
|
|
168
|
+
updated_at = datetime('now')
|
|
169
|
+
WHERE id = NEW.id;
|
|
170
|
+
END;
|
|
171
|
+
|
|
172
|
+
CREATE TABLE IF NOT EXISTS agentsam_plans (
|
|
173
|
+
id TEXT PRIMARY KEY,
|
|
174
|
+
account_id TEXT,
|
|
175
|
+
session_id TEXT,
|
|
176
|
+
agent_run_id TEXT REFERENCES agentsam_agent_run(id) ON DELETE SET NULL,
|
|
177
|
+
plan_type TEXT NOT NULL DEFAULT 'feature'
|
|
178
|
+
CHECK(plan_type IN ('daily','sprint','incident','feature','refactor','run')),
|
|
179
|
+
title TEXT NOT NULL,
|
|
180
|
+
status TEXT NOT NULL DEFAULT 'active'
|
|
181
|
+
CHECK(status IN ('draft','active','complete','abandoned')),
|
|
182
|
+
summary_text TEXT NOT NULL DEFAULT '',
|
|
183
|
+
token_budget INTEGER,
|
|
184
|
+
tokens_used INTEGER NOT NULL DEFAULT 0 CHECK(tokens_used >= 0),
|
|
185
|
+
cost_usd REAL NOT NULL DEFAULT 0 CHECK(cost_usd >= 0),
|
|
186
|
+
tasks_total INTEGER NOT NULL DEFAULT 0 CHECK(tasks_total >= 0),
|
|
187
|
+
tasks_done INTEGER NOT NULL DEFAULT 0 CHECK(tasks_done >= 0),
|
|
188
|
+
tasks_blocked INTEGER NOT NULL DEFAULT 0 CHECK(tasks_blocked >= 0),
|
|
189
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
190
|
+
created_at_unix INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
191
|
+
updated_at_unix INTEGER NOT NULL DEFAULT (unixepoch())
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
CREATE TABLE IF NOT EXISTS agentsam_todo (
|
|
195
|
+
id TEXT PRIMARY KEY,
|
|
196
|
+
account_id TEXT,
|
|
197
|
+
plan_id TEXT REFERENCES agentsam_plans(id) ON DELETE CASCADE,
|
|
198
|
+
agent_run_id TEXT REFERENCES agentsam_agent_run(id) ON DELETE SET NULL,
|
|
199
|
+
title TEXT NOT NULL,
|
|
200
|
+
description TEXT,
|
|
201
|
+
status TEXT NOT NULL DEFAULT 'open'
|
|
202
|
+
CHECK(status IN ('open','running','blocked','complete','cancelled')),
|
|
203
|
+
priority TEXT NOT NULL DEFAULT 'medium'
|
|
204
|
+
CHECK(priority IN ('low','medium','high','critical')),
|
|
205
|
+
sort_order INTEGER NOT NULL DEFAULT 50,
|
|
206
|
+
token_budget INTEGER,
|
|
207
|
+
tokens_used INTEGER NOT NULL DEFAULT 0 CHECK(tokens_used >= 0),
|
|
208
|
+
cost_usd REAL NOT NULL DEFAULT 0 CHECK(cost_usd >= 0),
|
|
209
|
+
requires_approval INTEGER NOT NULL DEFAULT 0 CHECK(requires_approval IN (0,1)),
|
|
210
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
211
|
+
started_at_unix INTEGER,
|
|
212
|
+
completed_at_unix INTEGER,
|
|
213
|
+
created_at_unix INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
214
|
+
updated_at_unix INTEGER NOT NULL DEFAULT (unixepoch())
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
CREATE INDEX IF NOT EXISTS idx_agentsam_todo_plan
|
|
218
|
+
ON agentsam_todo(plan_id, sort_order, created_at_unix);
|
|
219
|
+
|
|
220
|
+
CREATE TABLE IF NOT EXISTS agentsam_approval_queue (
|
|
221
|
+
id TEXT PRIMARY KEY DEFAULT ('appr_' || lower(hex(randomblob(8)))),
|
|
222
|
+
account_id TEXT,
|
|
223
|
+
session_id TEXT,
|
|
224
|
+
conversation_id TEXT,
|
|
225
|
+
agent_run_id TEXT REFERENCES agentsam_agent_run(id) ON DELETE SET NULL,
|
|
226
|
+
plan_id TEXT REFERENCES agentsam_plans(id) ON DELETE SET NULL,
|
|
227
|
+
todo_id TEXT REFERENCES agentsam_todo(id) ON DELETE SET NULL,
|
|
228
|
+
capability_key TEXT,
|
|
229
|
+
tool_name TEXT,
|
|
230
|
+
action_summary TEXT NOT NULL,
|
|
231
|
+
sanitized_input_json TEXT NOT NULL DEFAULT '{}',
|
|
232
|
+
response_json TEXT NOT NULL DEFAULT '{}',
|
|
233
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
234
|
+
risk_level TEXT NOT NULL DEFAULT 'medium'
|
|
235
|
+
CHECK (risk_level IN ('low','medium','high','critical')),
|
|
236
|
+
approval_type TEXT NOT NULL DEFAULT 'tool'
|
|
237
|
+
CHECK (approval_type IN (
|
|
238
|
+
'tool','workflow','command','script','deploy','db_write','r2_write',
|
|
239
|
+
'github_write','terminal','spawn','escalation','route_upgrade'
|
|
240
|
+
)),
|
|
241
|
+
status TEXT NOT NULL DEFAULT 'pending'
|
|
242
|
+
CHECK (status IN ('pending','approved','denied','expired')),
|
|
243
|
+
approved_by TEXT,
|
|
244
|
+
decided_at INTEGER,
|
|
245
|
+
expires_at INTEGER DEFAULT (unixepoch() + 300),
|
|
246
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
CREATE INDEX IF NOT EXISTS idx_agentsam_approval_pending
|
|
250
|
+
ON agentsam_approval_queue(status, expires_at)
|
|
251
|
+
WHERE status = 'pending';
|
|
252
|
+
|
|
253
|
+
CREATE TABLE IF NOT EXISTS active_timers (
|
|
254
|
+
id TEXT PRIMARY KEY,
|
|
255
|
+
account_id TEXT,
|
|
256
|
+
label TEXT NOT NULL DEFAULT '',
|
|
257
|
+
timer_kind TEXT NOT NULL CHECK (timer_kind IN ('stopwatch','countdown')),
|
|
258
|
+
status TEXT NOT NULL DEFAULT 'running'
|
|
259
|
+
CHECK (status IN ('running','paused','completed','cancelled','expired')),
|
|
260
|
+
started_at_unix INTEGER NOT NULL,
|
|
261
|
+
ends_at_unix INTEGER,
|
|
262
|
+
paused_at_unix INTEGER,
|
|
263
|
+
elapsed_seconds INTEGER NOT NULL DEFAULT 0,
|
|
264
|
+
completed_at_unix INTEGER,
|
|
265
|
+
agent_run_id TEXT REFERENCES agentsam_agent_run(id) ON DELETE CASCADE,
|
|
266
|
+
approval_queue_id TEXT REFERENCES agentsam_approval_queue(id) ON DELETE CASCADE,
|
|
267
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
268
|
+
updated_at_unix INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
269
|
+
CHECK (
|
|
270
|
+
timer_kind != 'countdown'
|
|
271
|
+
OR (ends_at_unix IS NOT NULL AND ends_at_unix > started_at_unix)
|
|
272
|
+
),
|
|
273
|
+
CHECK (agent_run_id IS NOT NULL OR approval_queue_id IS NOT NULL)
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
CREATE INDEX IF NOT EXISTS idx_active_timers_running
|
|
277
|
+
ON active_timers(status, ends_at_unix)
|
|
278
|
+
WHERE status = 'running';
|
|
279
|
+
|
|
280
|
+
CREATE TABLE IF NOT EXISTS agentsam_cron_runs (
|
|
281
|
+
id TEXT PRIMARY KEY DEFAULT ('acr_' || lower(hex(randomblob(8)))),
|
|
282
|
+
account_id TEXT,
|
|
283
|
+
job_name TEXT NOT NULL,
|
|
284
|
+
cron_expression TEXT,
|
|
285
|
+
status TEXT NOT NULL DEFAULT 'running'
|
|
286
|
+
CHECK(status IN ('running','completed','failed','skipped')),
|
|
287
|
+
started_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
288
|
+
completed_at INTEGER,
|
|
289
|
+
duration_ms INTEGER,
|
|
290
|
+
rows_read INTEGER NOT NULL DEFAULT 0,
|
|
291
|
+
rows_written INTEGER NOT NULL DEFAULT 0,
|
|
292
|
+
error_message TEXT,
|
|
293
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
294
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
CREATE INDEX IF NOT EXISTS idx_agentsam_cron_runs_job_started
|
|
298
|
+
ON agentsam_cron_runs(job_name, started_at DESC);
|