@arnilo/prism 0.6.0 → 0.8.0
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/CHANGELOG.md +79 -5
- package/README.md +12 -11
- package/dist/agent-approval.d.ts +4 -0
- package/dist/agent-approval.js +5 -1
- package/dist/agent-definitions.js +1 -0
- package/dist/agent-run-lifecycle.js +39 -4
- package/dist/agent-run-state.d.ts +18 -0
- package/dist/agent-run-state.js +39 -9
- package/dist/agent-session/helpers.js +6 -1
- package/dist/agent-session/session/assemble.js +159 -7
- package/dist/agent-session/session/persist.d.ts +16 -0
- package/dist/agent-session/session/persist.js +64 -4
- package/dist/agent-session/session/provider-round.d.ts +3 -3
- package/dist/agent-session/session/provider-round.js +12 -6
- package/dist/agent-session/session/tool-round.js +5 -1
- package/dist/agent-session/session/types.d.ts +22 -1
- package/dist/agent-session/session.d.ts +16 -0
- package/dist/agent-session/session.js +42 -3
- package/dist/artifacts.d.ts +39 -1
- package/dist/artifacts.js +73 -0
- package/dist/attention-compiler.d.ts +121 -0
- package/dist/attention-compiler.js +479 -0
- package/dist/checkpoints.js +7 -11
- package/dist/cli-init.js +20 -6
- package/dist/context-budget.d.ts +20 -1
- package/dist/context-budget.js +10 -1
- package/dist/contracts-core/agent.d.ts +7 -0
- package/dist/contracts-core/attention.d.ts +66 -0
- package/dist/contracts-core/attention.js +2 -0
- package/dist/contracts-core/compaction.d.ts +59 -0
- package/dist/contracts-core/compaction.js +77 -1
- package/dist/contracts-core/content.d.ts +5 -0
- package/dist/contracts-core/loop.d.ts +42 -0
- package/dist/contracts-core/provider.d.ts +4 -0
- package/dist/contracts-core/run-limits.d.ts +2 -0
- package/dist/contracts-core.d.ts +1 -0
- package/dist/contracts-core.js +1 -0
- package/dist/contracts-protocol.d.ts +44 -3
- package/dist/contracts-run-state.d.ts +32 -5
- package/dist/evidence-grounding.d.ts +29 -0
- package/dist/evidence-grounding.js +162 -0
- package/dist/host-composition.d.ts +91 -0
- package/dist/host-composition.js +279 -0
- package/dist/index.d.ts +13 -6
- package/dist/index.js +7 -4
- package/dist/input.d.ts +13 -1
- package/dist/input.js +40 -1
- package/dist/provider-events.d.ts +3 -1
- package/dist/provider-events.js +2 -2
- package/dist/providers/transport.d.ts +3 -1
- package/dist/providers/transport.js +36 -0
- package/dist/redaction.js +18 -2
- package/dist/run-bundle.d.ts +89 -0
- package/dist/run-bundle.js +149 -0
- package/dist/secure-agent.d.ts +2 -0
- package/dist/secure-agent.js +6 -1
- package/dist/testing/state-concurrency-conformance.js +5 -12
- package/dist/tool-result-fold.d.ts +12 -0
- package/dist/tool-result-fold.js +13 -6
- package/dist/tools.d.ts +10 -0
- package/dist/tools.js +41 -0
- package/docs/acp-agent.md +42 -11
- package/docs/acp.md +2 -1
- package/docs/ag-ui.md +10 -3
- package/docs/agent-definitions.md +9 -1
- package/docs/agent-events.md +4 -1
- package/docs/agent-loops.md +33 -0
- package/docs/agent-session-runtime.md +8 -7
- package/docs/attention-compiler.md +272 -0
- package/docs/cli-rpc.md +4 -2
- package/docs/coding-agent-tools.md +1 -1
- package/docs/coding-security.md +6 -3
- package/docs/coding-tools.md +0 -1
- package/docs/coding-workspaces.md +22 -0
- package/docs/compaction-and-retry.md +36 -4
- package/docs/compaction-observational-memory.md +63 -10
- package/docs/connected-apps.md +116 -0
- package/docs/context-and-skills.md +17 -2
- package/docs/conversations.md +1 -1
- package/docs/core.md +1 -1
- package/docs/dev-inspector.md +4 -0
- package/docs/device-adapters.md +1 -0
- package/docs/diagrams.md +6 -6
- package/docs/document-reader.md +18 -10
- package/docs/documents.md +40 -11
- package/docs/durable-runs.md +87 -0
- package/docs/enterprise-postgres-state.md +6 -2
- package/docs/evaluations.md +168 -4
- package/docs/execution-timeline.md +186 -0
- package/docs/guardrails.md +33 -0
- package/docs/history/0.7.0-primitive-review.md +254 -0
- package/docs/history/079-messaging-primitive-review.md +391 -0
- package/docs/history/080-messaging-followon-primitive-review.md +234 -0
- package/docs/history/081-connected-apps-primitive-review.md +74 -0
- package/docs/history/083-prism-work-primitive-review.md +84 -0
- package/docs/history/084-primitive-review.md +96 -0
- package/docs/history/085-honesty-and-cut-primitive-review.md +91 -0
- package/docs/history/README.md +5 -0
- package/docs/history/migration-0.0.md +2 -2
- package/docs/history/release-handoffs.md +75 -1
- package/docs/host-compositions.md +149 -0
- package/docs/host-security.md +2 -2
- package/docs/hosted-sandboxes.md +94 -0
- package/docs/index.md +82 -45
- package/docs/input-and-prompt-assembly.md +1 -0
- package/docs/knowledge-sync.md +84 -0
- package/docs/language-intelligence.md +1 -1
- package/docs/live-testing.md +8 -3
- package/docs/mcp-tools.md +3 -1
- package/docs/memory-fabric.md +416 -0
- package/docs/messaging-channel-operations.md +166 -0
- package/docs/messaging-channels.md +150 -0
- package/docs/migrate-to-0.5.md +1 -1
- package/docs/migrate-to-0.6.md +1 -0
- package/docs/migrate-to-0.7.md +345 -0
- package/docs/migrate-to-0.8.md +124 -0
- package/docs/migration.md +43 -1
- package/docs/model-registry.md +12 -2
- package/docs/model-routing.md +79 -4
- package/docs/multi-agent-patterns.md +20 -6
- package/docs/observability.md +52 -1
- package/docs/openapi-tools.md +1 -1
- package/docs/operations.md +14 -4
- package/docs/options-index.md +47 -3
- package/docs/peer-dependencies.md +12 -10
- package/docs/postgres-persistence.md +1 -1
- package/docs/process-sessions.md +3 -1
- package/docs/prompt-registry.md +1 -1
- package/docs/provider-caching.md +4 -2
- package/docs/provider-conformance.md +1 -1
- package/docs/provider-layer.md +2 -2
- package/docs/provider-packages.md +22 -22
- package/docs/providers/bedrock.md +71 -7
- package/docs/providers/neuralwatt.md +5 -1
- package/docs/providers/openai.md +1 -1
- package/docs/rag.md +24 -8
- package/docs/realtime-voice.md +87 -0
- package/docs/release-and-install.md +53 -45
- package/docs/run-bundle.md +92 -0
- package/docs/runs-and-usage.md +17 -2
- package/docs/server.md +7 -3
- package/docs/sheets.md +9 -9
- package/docs/signal-channel.md +112 -0
- package/docs/speech.md +7 -1
- package/docs/sqlite-persistence.md +1 -1
- package/docs/supervisors.md +33 -5
- package/docs/telegram-channel.md +157 -0
- package/docs/testing.md +2 -2
- package/docs/thinking-and-reasoning.md +3 -1
- package/docs/tools.md +6 -5
- package/docs/web-tools.md +2 -1
- package/docs/wiki.md +1 -1
- package/docs/work-artifacts-and-review.md +14 -4
- package/docs/work-connectors.md +12 -10
- package/docs/work-sandbox.md +115 -0
- package/docs/work-tools.md +50 -18
- package/docs/workflows.md +69 -1
- package/docs/working-and-semantic-memory.md +25 -14
- package/package.json +5 -3
- package/templates/README.md +2 -0
- package/templates/business-worker/README.md.tmpl +19 -0
- package/templates/business-worker/env.example.tmpl +1 -0
- package/templates/business-worker/gitignore.tmpl +11 -0
- package/templates/business-worker/manifest.json +12 -0
- package/templates/business-worker/package.json.tmpl +23 -0
- package/templates/business-worker/src/agent.ts.tmpl +92 -0
- package/templates/business-worker/src/index.ts.tmpl +13 -0
- package/templates/business-worker/src/tests/agent.test.ts.tmpl +77 -0
- package/templates/business-worker/tsconfig.json.tmpl +15 -0
- package/templates/personal-assistant/README.md.tmpl +18 -0
- package/templates/personal-assistant/env.example.tmpl +1 -0
- package/templates/personal-assistant/gitignore.tmpl +11 -0
- package/templates/personal-assistant/manifest.json +11 -0
- package/templates/personal-assistant/package.json.tmpl +23 -0
- package/templates/personal-assistant/src/agent.ts.tmpl +65 -0
- package/templates/personal-assistant/src/index.ts.tmpl +13 -0
- package/templates/personal-assistant/src/tests/agent.test.ts.tmpl +28 -0
- package/templates/personal-assistant/tsconfig.json.tmpl +15 -0
package/dist/index.js
CHANGED
|
@@ -4,7 +4,8 @@ export { dispatchToolCallsInOrder, generateValidateReviseLoop, isAgentLoopOption
|
|
|
4
4
|
export { createAgentRunLifecycle } from "./agent-run-lifecycle.js";
|
|
5
5
|
export { AGENT_RUN_STATE_NAMESPACE, AGENT_RUN_STATE_SCHEMA_VERSION, agentFingerprint, DEFAULT_MAX_AGENT_RUN_STATE_BYTES, HARD_MAX_AGENT_RUN_STATE_BYTES, loadAgentRunState, } from "./agent-run-state.js";
|
|
6
6
|
export { createAgent, createAgentSession, resumeAgentRun, resumeAgentRunStream } from "./agents.js";
|
|
7
|
-
export { ARTIFACT_BODY_ERROR_CODES, ARTIFACT_CHECKPOINT_NAMESPACE, ArtifactBodyStoreError, ArtifactError, artifactApprovalState, artifactCheckpointKey, } from "./artifacts.js";
|
|
7
|
+
export { ARTIFACT_BODY_ERROR_CODES, ARTIFACT_CHECKPOINT_NAMESPACE, ArtifactBodyStoreError, ArtifactError, approvalEvidenceIntact, artifactApprovalState, artifactCheckpointKey, checkCitationIntegrity, citationBindingDigest, HARD_CITATION_EXCERPT_BYTES, } from "./artifacts.js";
|
|
8
|
+
export { ATTENTION_BUDGET_ERROR_CODE, AttentionBudgetError, createAttentionCompiler, createAttentionTruncationTrigger, DEFAULT_ATTENTION_COMPACT_RATIO, DEFAULT_ATTENTION_KEEP_LAST, DEFAULT_ATTENTION_RESERVE_TOKENS, DEFAULT_ATTENTION_THINKING_KEEP_TURNS, DEFAULT_ATTENTION_TRIGGER_RATIO, DEFAULT_ATTENTION_TRUNCATION_THRESHOLD, isAttentionBudgetError, resolveAttentionReserveTokens, resolveInputCap, resolveRunAttentionCompiler, } from "./attention-compiler.js";
|
|
8
9
|
export { applyCacheControl, cacheHitRate, cacheSavings, cacheUsageReport, mapCacheRetention, resolveBreakpoint, sanitizeCacheKey, systemCacheControlField, } from "./cache-helpers.js";
|
|
9
10
|
export { CACHE_TELEMETRY_OVERFLOW_KEY, CacheTelemetryError, createCacheTelemetry, DEFAULT_CACHE_TELEMETRY_CAP, } from "./cache-telemetry.js";
|
|
10
11
|
export { createProviderCapture } from "./capture.js";
|
|
@@ -13,7 +14,7 @@ export { createDefaultCompactionStrategy, isCompactionEntryData } from "./compac
|
|
|
13
14
|
export { assertJsonObject, isJsonObject, loadConfigLayers, mergeConfigLayers } from "./config.js";
|
|
14
15
|
export { assertDeclaredMediaTypeMatches, assertMediaBlocksWithinBounds, assertMessagesSupportModelCapabilities, assertModelSupportsContentBlocks, assertSsrfAllowedUrl, collectMessageContentBlocks, contentBlockInputModality, DEFAULT_MAX_AUDIO_DURATION_MS, DEFAULT_MAX_MEDIA_ITEM_BYTES, DEFAULT_MAX_MEDIA_ITEMS_PER_REQUEST, DEFAULT_MAX_MEDIA_REQUEST_BYTES, DEFAULT_MEDIA_FETCH_TIMEOUT_MS, loadBoundedBinaryResource, MediaContentError, MODEL_INPUT_CAPABILITIES, resolveMediaContentBlock, resolveMediaContentBlocks, sniffMediaMimeType, UnsupportedModalityError, } from "./content.js";
|
|
15
16
|
export { applyContextBudget, CONTEXT_BUDGET_ERROR_CODE, CONTEXT_BUDGET_REPORT_METADATA_KEY, ContextBudgetError, DEFAULT_MAX_CONTEXT_BUDGET_OMISSIONS, estimateAssemblyTokens, estimateMessageBytes, estimateMessageTokens, estimateTextBytes, estimateTextTokens, getContextBudgetReport, HARD_MAX_CONTEXT_BUDGET_BYTES, HARD_MAX_CONTEXT_BUDGET_OMISSIONS, HARD_MAX_CONTEXT_BUDGET_TOKENS, isContextBudgetError, resolveContextBudget, } from "./context-budget.js";
|
|
16
|
-
export { AgentDecisionError, AgentDelegationSuspendedError, AgentLoopStateError, AgentRunError, AgentRunStateError, assertBatchJobsSupported, assertEmbeddingsSupported, assertImageGenerationSupported, assertModerationSupported, assertSessionMetadataKey, assertSpeechSupported, assertTranscriptionSupported, assertVideoGenerationSupported, BatchJobsError, DEFAULT_MAX_PENDING_DECISIONS, DEFAULT_MAX_PENDING_STEER_BYTES, DEFAULT_MAX_PENDING_STEERS, DEFAULT_MAX_SESSION_SEARCH_CURSOR_BYTES, DEFAULT_MAX_SESSION_SEARCH_FTS_CANDIDATES, DEFAULT_MAX_SESSION_SEARCH_LINEAR_BYTES, DEFAULT_MAX_SESSION_SEARCH_LINEAR_ENTRIES, DEFAULT_MAX_SESSION_SEARCH_LINEAR_SESSIONS, DEFAULT_MAX_SESSION_SEARCH_QUERY_BYTES, DEFAULT_MAX_SESSION_SEARCH_SNIPPET_BYTES, DEFAULT_MAX_STICKY_DECISIONS, DEFAULT_SESSION_SEARCH_LIMIT, DEFAULT_SNAPSHOT_CACHE_TTL_MS, EmbeddingsError, HARD_MAX_ACTION_CONSTRAINT_BYTES, HARD_MAX_ACTION_CONSTRAINTS, HARD_MAX_DECISION_REASON_BYTES, HARD_MAX_ELICITATION_BYTES, HARD_MAX_PENDING_DECISIONS, HARD_MAX_PENDING_STEER_BYTES, HARD_MAX_PENDING_STEERS, HARD_MAX_SESSION_SEARCH_CURSOR_BYTES, HARD_MAX_SESSION_SEARCH_FTS_CANDIDATES, HARD_MAX_SESSION_SEARCH_LIMIT, HARD_MAX_SESSION_SEARCH_LINEAR_BYTES, HARD_MAX_SESSION_SEARCH_LINEAR_ENTRIES, HARD_MAX_SESSION_SEARCH_LINEAR_SESSIONS, HARD_MAX_SESSION_SEARCH_QUERY_BYTES, HARD_MAX_SESSION_SEARCH_SNIPPET_BYTES, HARD_MAX_SNAPSHOT_CACHE_TTL_MS, HARD_MAX_STICKY_DECISIONS, ImageGenerationError, isBatchJobTerminal, isSessionAppendConflict, isSessionEntryKind, isSessionMetadataConflict, isSessionSearchUnsupported, MAX_ACTION_CONSTRAINT_BYTES, MAX_ACTION_CONSTRAINTS, MAX_ATTRIBUTION_DEPTH, MAX_DECISION_REASON_BYTES, MAX_ELICITATION_BYTES, ModerationError, modelSupportsBatchJobs, modelSupportsEmbeddings, modelSupportsImageGeneration, modelSupportsModeration, modelSupportsSpeech, modelSupportsTranscription, modelSupportsVideoGeneration, pollBatch, resolveSessionSearchQuery, SESSION_APPEND_CONFLICT_CODE, SESSION_ENTRY_KINDS, SESSION_ENTRY_SCHEMA_VERSION, SESSION_METADATA_CONFLICT_CODE, SESSION_SEARCH_UNSUPPORTED_CODE, SESSION_SEARCH_WORKSPACE_METADATA_KEY, SessionAppendConflictError, SessionMetadataConflictError, SessionSearchUnsupportedError, SpeechError, TranscriptionError, VideoGenerationError, } from "./contracts.js";
|
|
17
|
+
export { AgentDecisionError, AgentDelegationSuspendedError, AgentLoopStateError, AgentRunError, AgentRunStateError, assertBatchJobsSupported, assertCompactionTrigger, assertEmbeddingsSupported, assertImageGenerationSupported, assertModerationSupported, assertSessionMetadataKey, assertSpeechSupported, assertTranscriptionSupported, assertVideoGenerationSupported, BatchJobsError, DEFAULT_MAX_PENDING_DECISIONS, DEFAULT_MAX_PENDING_STEER_BYTES, DEFAULT_MAX_PENDING_STEERS, DEFAULT_MAX_SESSION_SEARCH_CURSOR_BYTES, DEFAULT_MAX_SESSION_SEARCH_FTS_CANDIDATES, DEFAULT_MAX_SESSION_SEARCH_LINEAR_BYTES, DEFAULT_MAX_SESSION_SEARCH_LINEAR_ENTRIES, DEFAULT_MAX_SESSION_SEARCH_LINEAR_SESSIONS, DEFAULT_MAX_SESSION_SEARCH_QUERY_BYTES, DEFAULT_MAX_SESSION_SEARCH_SNIPPET_BYTES, DEFAULT_MAX_STICKY_DECISIONS, DEFAULT_SESSION_SEARCH_LIMIT, DEFAULT_SNAPSHOT_CACHE_TTL_MS, EmbeddingsError, HARD_MAX_ACTION_CONSTRAINT_BYTES, HARD_MAX_ACTION_CONSTRAINTS, HARD_MAX_DECISION_REASON_BYTES, HARD_MAX_ELICITATION_BYTES, HARD_MAX_PENDING_DECISIONS, HARD_MAX_PENDING_STEER_BYTES, HARD_MAX_PENDING_STEERS, HARD_MAX_SESSION_SEARCH_CURSOR_BYTES, HARD_MAX_SESSION_SEARCH_FTS_CANDIDATES, HARD_MAX_SESSION_SEARCH_LIMIT, HARD_MAX_SESSION_SEARCH_LINEAR_BYTES, HARD_MAX_SESSION_SEARCH_LINEAR_ENTRIES, HARD_MAX_SESSION_SEARCH_LINEAR_SESSIONS, HARD_MAX_SESSION_SEARCH_QUERY_BYTES, HARD_MAX_SESSION_SEARCH_SNIPPET_BYTES, HARD_MAX_SNAPSHOT_CACHE_TTL_MS, HARD_MAX_STICKY_DECISIONS, ImageGenerationError, isBatchJobTerminal, isSessionAppendConflict, isSessionEntryKind, isSessionMetadataConflict, isSessionSearchUnsupported, MAX_ACTION_CONSTRAINT_BYTES, MAX_ACTION_CONSTRAINTS, MAX_ATTRIBUTION_DEPTH, MAX_DECISION_REASON_BYTES, MAX_ELICITATION_BYTES, ModerationError, modelSupportsBatchJobs, modelSupportsEmbeddings, modelSupportsImageGeneration, modelSupportsModeration, modelSupportsSpeech, modelSupportsTranscription, modelSupportsVideoGeneration, pollBatch, resolveSessionSearchQuery, resolveShouldCompact, SESSION_APPEND_CONFLICT_CODE, SESSION_ENTRY_KINDS, SESSION_ENTRY_SCHEMA_VERSION, SESSION_METADATA_CONFLICT_CODE, SESSION_SEARCH_UNSUPPORTED_CODE, SESSION_SEARCH_WORKSPACE_METADATA_KEY, SessionAppendConflictError, SessionMetadataConflictError, SessionSearchUnsupportedError, SpeechError, TranscriptionError, VideoGenerationError, } from "./contracts.js";
|
|
17
18
|
export { parseAgentFile, parseSkillFile } from "./contribution-parsing.js";
|
|
18
19
|
export { createContributionRegistries, createContributionRegistry, registerDiscoveredContributions } from "./contributions.js";
|
|
19
20
|
export { CONVERSATION_METADATA_KEY, ConversationError, conversationMarkerMetadata, conversationThreadFromRecord, DEFAULT_MAX_CONVERSATION_CURSOR_BYTES, decodeConversationReplayCursor, encodeConversationReplayCursor, HARD_MAX_CONVERSATION_CURSOR_BYTES, } from "./conversations.js";
|
|
@@ -21,6 +22,7 @@ export { createChainedCredentialResolver, createEnvCredentialResolver, createExp
|
|
|
21
22
|
export { createDelegatedAgentStep, DelegatedAgentStepError, MAX_DELEGATED_AGENT_DURATION_MS, MAX_DELEGATED_AGENT_EVENT_BYTES, MAX_DELEGATED_AGENT_ID_BYTES, MAX_DELEGATED_AGENT_NAME_BYTES, MAX_DELEGATED_AGENT_STEP_INDEX, MAX_DELEGATED_AGENT_TOKEN_COUNT, } from "./delegated-agent-step.js";
|
|
22
23
|
export { acceptDeviceChunk, assertDeviceAdmit, DEFAULT_DEVICE_MAX_CHUNK_BYTES, DEFAULT_DEVICE_MAX_CONCURRENT_SESSIONS, DevicePolicyError, HARD_DEVICE_MAX_CHUNK_BYTES, HARD_DEVICE_MAX_CONCURRENT_SESSIONS, redactDeviceTelemetry, resolveDevicePolicy, runDevicePolicyConformance, } from "./devices.js";
|
|
23
24
|
export { createEventMultiplexer, EVENT_MULTIPLEXER_SINGLE_CONSUMER_CODE, EventMultiplexerError } from "./event-multiplexer.js";
|
|
25
|
+
export { createClaimGroundingGuardrail } from "./evidence-grounding.js";
|
|
24
26
|
export { applyExecutionDecision, assertExecutionAllowed, checkExecution, ExecutionDeniedError } from "./execution-policy.js";
|
|
25
27
|
export { activateKernel, createExtensionEventBus, createExtensionKernel } from "./extensions.js";
|
|
26
28
|
export { createMemoryRunFeedbackStore, prepareRunFeedback, RunFeedbackError, requireRunFeedbackOwnership, runFeedbackPageLimit, } from "./feedback.js";
|
|
@@ -46,9 +48,10 @@ export { createProviderRegistry, createProviderResolver } from "./providers.js";
|
|
|
46
48
|
export { createSecretRedactor, errorToErrorInfo, redactAgentEvent, redactMessage, redactProviderRequest, redactRunLedgerRecord, redactSecrets, redactSessionEntry, resolveRedactor, } from "./redaction.js";
|
|
47
49
|
export { loadBinaryResource, loadJsonResource, loadManifestResource, loadTextResource } from "./resources.js";
|
|
48
50
|
export { createDefaultRetryPolicy, isTransientErrorInfo, waitForRetry } from "./retry.js";
|
|
51
|
+
export { RUN_BUNDLE_SCHEMA_VERSION, snapshotRunBundle } from "./run-bundle.js";
|
|
49
52
|
export { createBatchedRunLedger, DEFAULT_LEDGER_BATCH_BYTES, DEFAULT_LEDGER_BATCH_DELAY_MS, DEFAULT_LEDGER_BATCH_ENTRIES, HARD_LEDGER_BATCH_BYTES, HARD_LEDGER_BATCH_DELAY_MS, HARD_LEDGER_BATCH_ENTRIES, isFlushableRunLedger, } from "./run-ledger.js";
|
|
50
53
|
export { createRunLimitTracker, DEFAULT_RUN_LIMITS, HARD_RUN_LIMITS, RunLimitError, RunLimitTracker, resolveRunLimits, } from "./run-limits.js";
|
|
51
|
-
export { createSecureAgent } from "./secure-agent.js";
|
|
54
|
+
export { assertHostCompositionReadiness, createSecureAgent, HostCompositionError, inspectHostComposition, } from "./secure-agent.js";
|
|
52
55
|
export { assertPermission, assertTrusted, checkPermission, createStaticPermissionPolicy, createStaticTrustPolicy, denialToErrorInfo, isTrusted, PermissionDeniedError, TrustDeniedError, } from "./security.js";
|
|
53
56
|
export { createMemorySessionStore, createSessionEntry, getSessionBranchEntries, listSessionBranches, rebuildSessionContext, } from "./session-stores.js";
|
|
54
57
|
export { createChainedSettingsProvider, createStaticSettingsProvider } from "./settings.js";
|
|
@@ -66,6 +69,6 @@ export { createToolParameterValidator, createToolRegistry, dispatchToolCall, fil
|
|
|
66
69
|
export { trimTrailingSlashes } from "./trim-trailing-slashes.js";
|
|
67
70
|
export { resolveUseCaseModel, resolveUseCaseModelBinding, useCaseCredentialProviderId, } from "./use-case-model.js";
|
|
68
71
|
export const name = "prism";
|
|
69
|
-
export const version = "0.
|
|
72
|
+
export const version = "0.8.0";
|
|
70
73
|
export const description = "Agent harness for AI providers, agents, sessions, and tools.";
|
|
71
74
|
//# sourceMappingURL=index.js.map
|
package/dist/input.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { type AttentionStickyFrontier } from "./attention-compiler.js";
|
|
1
2
|
import { type ContextBudget } from "./context-budget.js";
|
|
2
|
-
import type { ContentBlock, ContextBlock, ContextProvider, ContextResolutionContext, InputBuildContext, InputBuilder, InstructionInjector, JsonObject, Message, ModelConfig, PromptBuilder, PromptBuildRequest, ProviderRequest, ProviderRequestOptions, ResourceLoader, Skill, ToolDefinition, ToolResult } from "./contracts.js";
|
|
3
|
+
import type { AttentionCompiler, AttentionCompilerOptions, AttentionReport, ContentBlock, ContextBlock, ContextProvider, ContextResolutionContext, InputBuildContext, InputBuilder, InstructionInjector, JsonObject, Message, ModelConfig, PromptBuilder, PromptBuildRequest, ProviderRequest, ProviderRequestOptions, ResourceLoader, Skill, ToolDefinition, ToolResult } from "./contracts.js";
|
|
3
4
|
import type { MiddlewareRegistry } from "./middleware.js";
|
|
4
5
|
import type { SecretRedactor } from "./redaction.js";
|
|
5
6
|
import { type LoadedSkillSet, type SkillsDisclosure } from "./skill-disclosure.js";
|
|
@@ -77,6 +78,17 @@ export interface AssembleProviderInputOptions extends DefaultInputBuildContext {
|
|
|
77
78
|
readonly contextBudget?: ContextBudget;
|
|
78
79
|
/** Resolved tool-result fold; projection-only, store untouched. */
|
|
79
80
|
readonly toolResultFold?: ResolvedToolResultFoldOptions;
|
|
81
|
+
/**
|
|
82
|
+
* Opt-in attention compiler: options are validated here (per call) or pass an existing
|
|
83
|
+
* `AttentionCompiler` to reuse one validation. Mutually exclusive with `contextBudget`,
|
|
84
|
+
* which would otherwise evict as a silent last resort after the compiler's stages.
|
|
85
|
+
*/
|
|
86
|
+
readonly attentionCompiler?: AttentionCompilerOptions | AttentionCompiler;
|
|
87
|
+
/** Per-session-leaf sticky frontier; omit for one-shot assemblies (no cross-turn stickiness). */
|
|
88
|
+
readonly attentionSticky?: AttentionStickyFrontier;
|
|
89
|
+
/** Called once per *mutated* turn with the report, so a host can emit telemetry: under-ratio
|
|
90
|
+
* turns never call it, and it runs before `input_assembly` middleware. */
|
|
91
|
+
readonly onAttentionReport?: (report: AttentionReport) => void;
|
|
80
92
|
}
|
|
81
93
|
export declare function createDefaultInputBuilder(): DefaultInputBuilder;
|
|
82
94
|
export declare function resolveContextProviders(options: ResolveContextOptions): Promise<readonly ContextBlock[]>;
|
package/dist/input.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { compileAttention, createAttentionCompiler } from "./attention-compiler.js";
|
|
1
2
|
import { assertMessagesSupportModelCapabilities } from "./content.js";
|
|
2
3
|
import { applyContextBudget, CONTEXT_BUDGET_REPORT_METADATA_KEY } from "./context-budget.js";
|
|
3
4
|
import { runInstructionInjectors } from "./instruction-injection.js";
|
|
@@ -133,7 +134,41 @@ export async function assembleProviderInput(options) {
|
|
|
133
134
|
}
|
|
134
135
|
let demotedSkillBodies;
|
|
135
136
|
let budgetReport;
|
|
136
|
-
if (options.
|
|
137
|
+
if (options.attentionCompiler) {
|
|
138
|
+
if (options.contextBudget) {
|
|
139
|
+
throw new TypeError("attentionCompiler and contextBudget are mutually exclusive: the compiler raises AttentionBudgetError instead of evicting");
|
|
140
|
+
}
|
|
141
|
+
// Same default-groups path as the budget branch: the compiler needs the assembled groups
|
|
142
|
+
// (and the provider context blocks) to measure one cost for the whole request.
|
|
143
|
+
const groups = await buildDefaultInputMessageGroups(options.input, buildContext);
|
|
144
|
+
context = await resolveContextProviders({
|
|
145
|
+
providers: options.contextProviders,
|
|
146
|
+
messages: flattenInputGroups(groups, layout),
|
|
147
|
+
injectedBlocks: injectorContribs.contextBlocks.length ? injectorContribs.contextBlocks : undefined,
|
|
148
|
+
middleware: options.middleware,
|
|
149
|
+
...baseContext,
|
|
150
|
+
});
|
|
151
|
+
const compiled = await compileAttention({
|
|
152
|
+
compiler: resolveAttentionCompiler(options.attentionCompiler, options.model),
|
|
153
|
+
groups,
|
|
154
|
+
context,
|
|
155
|
+
skills,
|
|
156
|
+
tools,
|
|
157
|
+
fold: options.toolResultFold,
|
|
158
|
+
frontier: options.attentionSticky,
|
|
159
|
+
redactor: options.redactor,
|
|
160
|
+
signal: options.signal,
|
|
161
|
+
turn,
|
|
162
|
+
sessionId: options.sessionId,
|
|
163
|
+
runId: options.runId,
|
|
164
|
+
});
|
|
165
|
+
if (compiled.mutated)
|
|
166
|
+
options.onAttentionReport?.(compiled.report);
|
|
167
|
+
messages = flattenInputGroups(compiled.groups, layout);
|
|
168
|
+
if (buildContext.middleware)
|
|
169
|
+
messages = await buildContext.middleware.run("input_assembly", messages);
|
|
170
|
+
}
|
|
171
|
+
else if (options.contextBudget) {
|
|
137
172
|
// ponytail: budget path always uses default groups so eviction kinds stay deterministic;
|
|
138
173
|
// custom inputBuilder still honored when contextBudget is absent.
|
|
139
174
|
const groups = await buildDefaultInputMessageGroups(options.input, buildContext);
|
|
@@ -217,6 +252,10 @@ export async function assembleProviderInput(options) {
|
|
|
217
252
|
signal: options.signal,
|
|
218
253
|
}, { sessionId: options.sessionId });
|
|
219
254
|
}
|
|
255
|
+
/** A resolved handle is reused as-is; raw options are validated for this call only. */
|
|
256
|
+
function resolveAttentionCompiler(value, model) {
|
|
257
|
+
return "inputCap" in value ? value : createAttentionCompiler(value, { model });
|
|
258
|
+
}
|
|
220
259
|
async function buildDefaultInputMessageGroups(input, context) {
|
|
221
260
|
return {
|
|
222
261
|
instructions: [
|
|
@@ -14,7 +14,9 @@ export declare function providerContinuationRequired(cursor: string, reason?: st
|
|
|
14
14
|
export declare function reconstructToolCallDeltas(events: readonly ProviderEvent[]): readonly ToolCallContent[];
|
|
15
15
|
export declare function providerUsage(usage: Usage): ProviderEvent;
|
|
16
16
|
export declare function providerDone(usage?: Usage): ProviderEvent;
|
|
17
|
-
export declare function providerError(error: unknown, secrets?: readonly (string | undefined)[]): ProviderEvent
|
|
17
|
+
export declare function providerError(error: unknown, secrets?: readonly (string | undefined)[]): Extract<ProviderEvent, {
|
|
18
|
+
type: "error";
|
|
19
|
+
}>;
|
|
18
20
|
export declare function toolCallContent(id: string, name: string, args?: JsonObject): ToolCallContent;
|
|
19
21
|
/** Build a tool call from streamed arguments text; malformed JSON becomes a blocked call (no throw). */
|
|
20
22
|
export declare function toolCallFromArgumentsText(id: string, name: string, argumentsText: string): ToolCallContent;
|
package/dist/provider-events.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ProviderTransportError, tryParseJsonObjectArguments } from "./providers/transport.js";
|
|
1
|
+
import { classifyProviderFailure, ProviderTransportError, tryParseJsonObjectArguments } from "./providers/transport.js";
|
|
2
2
|
import { errorToErrorInfo } from "./redaction.js";
|
|
3
3
|
export function providerTextDelta(text) {
|
|
4
4
|
return { type: "content_delta", content: { type: "text", text } };
|
|
@@ -51,7 +51,7 @@ export function providerDone(usage) {
|
|
|
51
51
|
}
|
|
52
52
|
export function providerError(error, secrets = []) {
|
|
53
53
|
const info = errorToErrorInfo(error, secrets);
|
|
54
|
-
return { type: "error", error: info };
|
|
54
|
+
return { type: "error", error: info.failureClass ? info : { ...info, failureClass: classifyProviderFailure(error) } };
|
|
55
55
|
}
|
|
56
56
|
export function toolCallContent(id, name, args = {}) {
|
|
57
57
|
return { type: "tool_call", id, name, arguments: args };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { JsonObject } from "../contracts.js";
|
|
1
|
+
import type { JsonObject, ProviderFailureClass } from "../contracts.js";
|
|
2
2
|
export declare const DEFAULT_MAX_EVENT_BYTES = 262144;
|
|
3
3
|
export declare const DEFAULT_MAX_BUFFER_BYTES = 524288;
|
|
4
4
|
export declare const DEFAULT_MAX_RESPONSE_BODY_BYTES = 65536;
|
|
@@ -15,6 +15,8 @@ export interface SseEvent {
|
|
|
15
15
|
readonly comments?: readonly string[];
|
|
16
16
|
}
|
|
17
17
|
export type ProviderTransportErrorCode = "sse_buffer_overflow" | "sse_event_overflow" | "response_body_overflow" | "aborted" | "invalid_json_arguments" | "incomplete_delta" | "response_body_shape";
|
|
18
|
+
/** Maps already-captured provider transport evidence to advisory outcome metadata. */
|
|
19
|
+
export declare function classifyProviderFailure(error: unknown): ProviderFailureClass;
|
|
18
20
|
export declare class ProviderTransportError extends Error {
|
|
19
21
|
readonly code: ProviderTransportErrorCode;
|
|
20
22
|
readonly limitBytes?: number;
|
|
@@ -3,6 +3,22 @@ export const DEFAULT_MAX_EVENT_BYTES = 262_144;
|
|
|
3
3
|
export const DEFAULT_MAX_BUFFER_BYTES = 524_288;
|
|
4
4
|
export const DEFAULT_MAX_RESPONSE_BODY_BYTES = 65_536;
|
|
5
5
|
export const DEFAULT_MAX_ARGUMENT_BYTES = 262_144;
|
|
6
|
+
const QUOTA_BODY = /quota|usage[\s_-]*limit|insufficient[\s_-]*(?:quota|credit|balance)|billing[\s_-]*(?:limit|quota)/i;
|
|
7
|
+
const TRANSIENT_NETWORK_CODES = new Set(["ECONNRESET", "ECONNREFUSED", "EAI_AGAIN", "ENETUNREACH", "ETIMEDOUT", "UND_ERR_CONNECT_TIMEOUT"]);
|
|
8
|
+
/** Maps already-captured provider transport evidence to advisory outcome metadata. */
|
|
9
|
+
export function classifyProviderFailure(error) {
|
|
10
|
+
const status = readHttpStatus(error);
|
|
11
|
+
if (status === 401 || status === 403)
|
|
12
|
+
return "auth";
|
|
13
|
+
if (status === 429)
|
|
14
|
+
return QUOTA_BODY.test(errorMessage(error)) ? "quota" : "rate_limited";
|
|
15
|
+
if (status !== undefined)
|
|
16
|
+
return status >= 500 ? "transient" : status >= 400 ? "permanent" : "unknown";
|
|
17
|
+
const cause = readField(error, "cause");
|
|
18
|
+
if (isTransientNetworkCode(readField(error, "code")) || isTransientNetworkCode(readField(cause, "code")))
|
|
19
|
+
return "transient";
|
|
20
|
+
return "unknown";
|
|
21
|
+
}
|
|
6
22
|
export class ProviderTransportError extends Error {
|
|
7
23
|
code;
|
|
8
24
|
limitBytes;
|
|
@@ -22,8 +38,28 @@ export function httpStatusError(prefix, response, bodyText) {
|
|
|
22
38
|
const hint = parseRetryAfterMs(response.headers.get("retry-after"));
|
|
23
39
|
if (hint !== undefined)
|
|
24
40
|
error.retryAfterMs = hint;
|
|
41
|
+
Object.defineProperty(error, "failureClass", { value: classifyProviderFailure(error), enumerable: true });
|
|
25
42
|
return error;
|
|
26
43
|
}
|
|
44
|
+
function readHttpStatus(error) {
|
|
45
|
+
for (const key of ["code", "status", "statusCode"]) {
|
|
46
|
+
const value = readField(error, key);
|
|
47
|
+
const status = typeof value === "number" ? value : typeof value === "string" && /^\d{3}$/.test(value) ? Number(value) : undefined;
|
|
48
|
+
if (status !== undefined && status >= 100 && status <= 599)
|
|
49
|
+
return status;
|
|
50
|
+
}
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
function readField(error, key) {
|
|
54
|
+
return error && typeof error === "object" && key in error ? error[key] : undefined;
|
|
55
|
+
}
|
|
56
|
+
function isTransientNetworkCode(value) {
|
|
57
|
+
return typeof value === "string" && TRANSIENT_NETWORK_CODES.has(value.toUpperCase());
|
|
58
|
+
}
|
|
59
|
+
function errorMessage(error) {
|
|
60
|
+
const cause = readField(error, "cause");
|
|
61
|
+
return [readField(error, "message"), readField(cause, "message")].filter((value) => typeof value === "string").join(" ");
|
|
62
|
+
}
|
|
27
63
|
/** Parse a `Retry-After` header (delay-seconds or HTTP-date) into milliseconds. */
|
|
28
64
|
export function parseRetryAfterMs(value, now = Date.now()) {
|
|
29
65
|
if (!value)
|
package/dist/redaction.js
CHANGED
|
@@ -167,19 +167,22 @@ export function errorToErrorInfo(error, secrets = []) {
|
|
|
167
167
|
const code = readErrorCode(error);
|
|
168
168
|
const retry = readRetryAfterMs(error);
|
|
169
169
|
const retryAfter = retry !== undefined ? { retryAfterMs: retry } : {};
|
|
170
|
+
const failureClass = readProviderFailureClass(error);
|
|
171
|
+
const failure = failureClass === undefined ? {} : { failureClass };
|
|
170
172
|
if (error instanceof Error) {
|
|
171
173
|
return {
|
|
172
174
|
name: error.name,
|
|
173
175
|
message: redactSecrets(error.message, secrets),
|
|
174
176
|
code,
|
|
177
|
+
...failure,
|
|
175
178
|
...retryAfter,
|
|
176
179
|
cause: error.cause ? redactSecrets(String(error.cause), secrets) : undefined,
|
|
177
180
|
};
|
|
178
181
|
}
|
|
179
182
|
if (error && typeof error === "object" && "message" in error) {
|
|
180
|
-
return { message: redactSecrets(String(error.message), secrets), code, ...retryAfter };
|
|
183
|
+
return { message: redactSecrets(String(error.message), secrets), code, ...failure, ...retryAfter };
|
|
181
184
|
}
|
|
182
|
-
return { message: redactSecrets(String(error), secrets), code, ...retryAfter };
|
|
185
|
+
return { message: redactSecrets(String(error), secrets), code, ...failure, ...retryAfter };
|
|
183
186
|
}
|
|
184
187
|
function readErrorCode(error) {
|
|
185
188
|
if (!error || typeof error !== "object" || !("code" in error))
|
|
@@ -193,4 +196,17 @@ function readRetryAfterMs(error) {
|
|
|
193
196
|
const value = error.retryAfterMs;
|
|
194
197
|
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : undefined;
|
|
195
198
|
}
|
|
199
|
+
function readProviderFailureClass(error) {
|
|
200
|
+
if (!error || typeof error !== "object" || !("failureClass" in error))
|
|
201
|
+
return undefined;
|
|
202
|
+
const value = error.failureClass;
|
|
203
|
+
return value === "quota" ||
|
|
204
|
+
value === "auth" ||
|
|
205
|
+
value === "rate_limited" ||
|
|
206
|
+
value === "transient" ||
|
|
207
|
+
value === "permanent" ||
|
|
208
|
+
value === "unknown"
|
|
209
|
+
? value
|
|
210
|
+
: undefined;
|
|
211
|
+
}
|
|
196
212
|
//# sourceMappingURL=redaction.js.map
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Agent, AgentSessionConfig, GuardrailStage, RunOptions } from "./contracts.js";
|
|
2
|
+
/** Report format revision. Any shape change bumps this so pinned digests cannot compare across formats. */
|
|
3
|
+
export declare const RUN_BUNDLE_SCHEMA_VERSION = 1;
|
|
4
|
+
/** Inspectable projection of the inputs a run actually resolves to. Frozen JSON, safe to persist and diff. */
|
|
5
|
+
export interface RunBundleSnapshot {
|
|
6
|
+
readonly schemaVersion: number;
|
|
7
|
+
/** `sha256:<64 hex>` over the canonicalized, redacted snapshot (this field excluded). */
|
|
8
|
+
readonly digest: string;
|
|
9
|
+
/** `agentFingerprint()` of the same agent/revision: the durable-resume identity behind this snapshot. */
|
|
10
|
+
readonly fingerprint: string;
|
|
11
|
+
readonly agent: {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly definitionRevision: string | null;
|
|
14
|
+
};
|
|
15
|
+
readonly systemPrompt: {
|
|
16
|
+
readonly disabled: boolean;
|
|
17
|
+
/** Digest of `AgentConfig.instructions`; the body never leaves the process. */
|
|
18
|
+
readonly instructionsDigest: string | null;
|
|
19
|
+
readonly contributions: readonly {
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly mode: string | null;
|
|
22
|
+
readonly source: string | null;
|
|
23
|
+
readonly digest: string;
|
|
24
|
+
}[];
|
|
25
|
+
};
|
|
26
|
+
readonly skills: readonly {
|
|
27
|
+
readonly name: string;
|
|
28
|
+
readonly instructionsDigest: string | null;
|
|
29
|
+
readonly toolNames: readonly string[];
|
|
30
|
+
}[];
|
|
31
|
+
/** Effective tool set: `run.toolNames` narrowing already applied, schemas reduced to digests. */
|
|
32
|
+
readonly tools: readonly {
|
|
33
|
+
readonly name: string;
|
|
34
|
+
readonly schemaDigest: string;
|
|
35
|
+
readonly exclusive: boolean;
|
|
36
|
+
readonly effect: string | null;
|
|
37
|
+
}[];
|
|
38
|
+
readonly activeSkills: readonly string[] | null;
|
|
39
|
+
readonly guardrails: readonly {
|
|
40
|
+
readonly name: string;
|
|
41
|
+
readonly stage: GuardrailStage;
|
|
42
|
+
readonly revision: string | null;
|
|
43
|
+
}[];
|
|
44
|
+
readonly loop: {
|
|
45
|
+
readonly strategy: string;
|
|
46
|
+
readonly revision: string | null;
|
|
47
|
+
};
|
|
48
|
+
readonly thinkingLevel: string | null;
|
|
49
|
+
readonly limits: Readonly<import("./contracts.js").ResolvedRunLimits>;
|
|
50
|
+
/** Host-shaped JSON as configured (`true`/`false`/options); `null` when unset. */
|
|
51
|
+
readonly attentionCompiler: unknown;
|
|
52
|
+
readonly model: {
|
|
53
|
+
readonly provider: string | null;
|
|
54
|
+
readonly model: string | null;
|
|
55
|
+
};
|
|
56
|
+
readonly requestPolicies: readonly string[];
|
|
57
|
+
/** Kinds only — never a connection string, path, or credential. */
|
|
58
|
+
readonly storage: {
|
|
59
|
+
readonly sessionStore: {
|
|
60
|
+
readonly kind: string;
|
|
61
|
+
readonly durable: boolean;
|
|
62
|
+
};
|
|
63
|
+
readonly checkpoints: {
|
|
64
|
+
readonly kind: string;
|
|
65
|
+
readonly durable: boolean;
|
|
66
|
+
};
|
|
67
|
+
readonly effectStore: {
|
|
68
|
+
readonly kind: string;
|
|
69
|
+
readonly durable: boolean;
|
|
70
|
+
};
|
|
71
|
+
readonly memory: {
|
|
72
|
+
readonly kind: string;
|
|
73
|
+
readonly durable: boolean;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export interface RunBundleSnapshotInput {
|
|
78
|
+
readonly agent: Agent;
|
|
79
|
+
/** Session-level inputs (store, leaf, cache TTL) that change what the run reads and writes. */
|
|
80
|
+
readonly config?: AgentSessionConfig;
|
|
81
|
+
readonly run?: RunOptions;
|
|
82
|
+
/** Optional memory store instance; only its kind/durability label is read, never its contents. */
|
|
83
|
+
readonly memory?: unknown;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Snapshots the effective run bundle: synchronous, in-memory, zero network and zero store reads.
|
|
87
|
+
* The counterpart of `agentFingerprint` for humans — same inputs, named fields, one stable digest to pin.
|
|
88
|
+
*/
|
|
89
|
+
export declare function snapshotRunBundle(input: RunBundleSnapshotInput): RunBundleSnapshot;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { agentFingerprint, BUILT_IN_LOOP_REVISIONS } from "./agent-run-state.js";
|
|
3
|
+
import { describeStorage } from "./host-composition.js";
|
|
4
|
+
import { canonicalizeJsonSchema } from "./providers/schema.js";
|
|
5
|
+
import { resolveRunLimits } from "./run-limits.js";
|
|
6
|
+
import { selectRunTools } from "./tools.js";
|
|
7
|
+
/** Report format revision. Any shape change bumps this so pinned digests cannot compare across formats. */
|
|
8
|
+
export const RUN_BUNDLE_SCHEMA_VERSION = 1;
|
|
9
|
+
/** Bounded by construction; a bundle larger than this is a host bug, not a snapshot to retain. */
|
|
10
|
+
const MAX_RUN_BUNDLE_BYTES = 512 * 1024;
|
|
11
|
+
/**
|
|
12
|
+
* Snapshots the effective run bundle: synchronous, in-memory, zero network and zero store reads.
|
|
13
|
+
* The counterpart of `agentFingerprint` for humans — same inputs, named fields, one stable digest to pin.
|
|
14
|
+
*/
|
|
15
|
+
export function snapshotRunBundle(input) {
|
|
16
|
+
const config = input.agent.config;
|
|
17
|
+
const run = input.run;
|
|
18
|
+
const redactor = run?.redactor ?? config.redactor;
|
|
19
|
+
const definitionRevision = run?.runState?.definitionRevision ?? config.runState?.definitionRevision ?? null;
|
|
20
|
+
const tools = selectRunTools(listTools(config.tools), run?.toolNames).tools;
|
|
21
|
+
const skills = listSkills(config.skills, run?.skills);
|
|
22
|
+
const model = run?.model ?? config.model;
|
|
23
|
+
const effectiveLoop = run?.loop ?? config.loop;
|
|
24
|
+
const systemPrompt = run?.systemPrompt ?? config.systemPrompt;
|
|
25
|
+
const policies = run?.providerRequestPolicies ?? config.providerRequestPolicies;
|
|
26
|
+
const snapshot = {
|
|
27
|
+
schemaVersion: RUN_BUNDLE_SCHEMA_VERSION,
|
|
28
|
+
fingerprint: agentFingerprint(input.agent, definitionRevision ?? ""),
|
|
29
|
+
agent: { id: agentId(input.agent), definitionRevision },
|
|
30
|
+
systemPrompt: {
|
|
31
|
+
disabled: systemPrompt === false,
|
|
32
|
+
instructionsDigest: hashText(config.instructions),
|
|
33
|
+
contributions: systemPrompt === false || systemPrompt === undefined
|
|
34
|
+
? []
|
|
35
|
+
: (Array.isArray(systemPrompt) ? systemPrompt : [systemPrompt]).map((contribution) => ({
|
|
36
|
+
id: contribution.id,
|
|
37
|
+
mode: contribution.mode ?? null,
|
|
38
|
+
source: contribution.source ?? null,
|
|
39
|
+
digest: hashText(contribution.text) ?? "",
|
|
40
|
+
})),
|
|
41
|
+
},
|
|
42
|
+
skills: skills.map((skill) => ({
|
|
43
|
+
name: skill.name,
|
|
44
|
+
instructionsDigest: hashText(skill.instructions),
|
|
45
|
+
toolNames: skill.toolNames ?? [],
|
|
46
|
+
})),
|
|
47
|
+
tools: tools.map((tool) => ({
|
|
48
|
+
name: tool.name,
|
|
49
|
+
schemaDigest: hashJson(canonicalizeJsonSchema(tool.parameters ?? { type: "object" })),
|
|
50
|
+
exclusive: tool.exclusive === true,
|
|
51
|
+
effect: tool.effect === undefined ? null : typeof tool.effect === "function" ? "classifier" : tool.effect.kind,
|
|
52
|
+
})),
|
|
53
|
+
activeSkills: run?.activeSkills ?? null,
|
|
54
|
+
guardrails: guardrailRows(config.guardrails, run?.guardrails),
|
|
55
|
+
loop: loopIdentity(effectiveLoop),
|
|
56
|
+
thinkingLevel: run?.thinkingLevel ?? config.thinkingLevel ?? null,
|
|
57
|
+
limits: resolveRunLimits(config.limits, run?.limits),
|
|
58
|
+
attentionCompiler: run?.attentionCompiler ?? config.attentionCompiler ?? null,
|
|
59
|
+
model: {
|
|
60
|
+
provider: typeof model === "string" ? (config.provider?.id ?? null) : (model?.provider ?? null),
|
|
61
|
+
model: typeof model === "string" ? model : (model?.model ?? null),
|
|
62
|
+
},
|
|
63
|
+
requestPolicies: policies === undefined ? [] : (Array.isArray(policies) ? policies : [policies]).map((policy) => policy.name),
|
|
64
|
+
storage: {
|
|
65
|
+
sessionStore: kindOf(describeStorage(input.config?.store ?? config.store, undefined)),
|
|
66
|
+
checkpoints: kindOf(describeStorage(undefined, (run?.runState ?? config.runState)?.checkpoints)),
|
|
67
|
+
effectStore: kindOf(describeStorage(run?.effectStore ?? config.effectStore, undefined)),
|
|
68
|
+
memory: kindOf(describeStorage(input.memory, undefined)),
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
const redacted = redactStrings(snapshot, redactor);
|
|
72
|
+
const bundle = deepFreeze({ ...redacted, digest: hashJson(canonicalizeJsonSchema(redacted)) });
|
|
73
|
+
const bytes = Buffer.byteLength(JSON.stringify(bundle), "utf8");
|
|
74
|
+
if (bytes > MAX_RUN_BUNDLE_BYTES) {
|
|
75
|
+
throw new TypeError(`Run bundle snapshot exceeds ${MAX_RUN_BUNDLE_BYTES} bytes`);
|
|
76
|
+
}
|
|
77
|
+
return bundle;
|
|
78
|
+
}
|
|
79
|
+
/** Keeps a store label a label: a declared `kind` that is really a connection string or path becomes `custom`. */
|
|
80
|
+
function kindOf(described) {
|
|
81
|
+
const raw = described.kind.toLowerCase();
|
|
82
|
+
return { kind: /^[a-z0-9_.-]{1,64}$/.test(raw) ? raw : "custom", durable: described.durable };
|
|
83
|
+
}
|
|
84
|
+
function agentId(agent) {
|
|
85
|
+
return agent.config.id ?? agent.config.name ?? "agent";
|
|
86
|
+
}
|
|
87
|
+
function listTools(tools) {
|
|
88
|
+
if (!tools)
|
|
89
|
+
return [];
|
|
90
|
+
return "list" in tools ? tools.list() : tools;
|
|
91
|
+
}
|
|
92
|
+
function listSkills(skills, runSkills) {
|
|
93
|
+
const listed = !skills ? [] : "list" in skills ? skills.list() : skills;
|
|
94
|
+
const byName = new Map(listed.map((skill) => [skill.name, skill]));
|
|
95
|
+
for (const skill of runSkills ?? [])
|
|
96
|
+
byName.set(skill.name, skill);
|
|
97
|
+
return [...byName.values()];
|
|
98
|
+
}
|
|
99
|
+
function guardrailRows(configGuardrails, runGuardrails) {
|
|
100
|
+
const rows = [];
|
|
101
|
+
for (const guardrails of [configGuardrails, runGuardrails]) {
|
|
102
|
+
if (!guardrails)
|
|
103
|
+
continue;
|
|
104
|
+
for (const stage of ["input", "output", "tool_input", "tool_output"]) {
|
|
105
|
+
const key = stage === "tool_input" ? "toolInput" : stage === "tool_output" ? "toolOutput" : stage;
|
|
106
|
+
for (const guardrail of guardrails[key] ?? []) {
|
|
107
|
+
rows.push({ name: guardrail.name, stage, revision: guardrail.revision ?? null });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return rows;
|
|
112
|
+
}
|
|
113
|
+
function loopIdentity(loop) {
|
|
114
|
+
if (typeof loop === "object" && loop && "strategy" in loop) {
|
|
115
|
+
return { strategy: loop.strategy, revision: BUILT_IN_LOOP_REVISIONS[loop.strategy] ?? null };
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
strategy: loop?.name ?? "single-shot",
|
|
119
|
+
revision: loop?.revision ?? BUILT_IN_LOOP_REVISIONS["single-shot"] ?? null,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/** `sha256:<64 hex>` over UTF-8 text — the same convention as `hashPromptBody` in `@arnilo/prism-core`. */
|
|
123
|
+
function hashText(text) {
|
|
124
|
+
if (text === undefined)
|
|
125
|
+
return null;
|
|
126
|
+
return `sha256:${createHash("sha256").update(text, "utf8").digest("hex")}`;
|
|
127
|
+
}
|
|
128
|
+
function hashJson(value) {
|
|
129
|
+
return `sha256:${createHash("sha256").update(JSON.stringify(value), "utf8").digest("hex")}`;
|
|
130
|
+
}
|
|
131
|
+
/** Redacts every string field so a pinned snapshot can never carry a secret. */
|
|
132
|
+
function redactStrings(value, redactor) {
|
|
133
|
+
if (typeof value === "string")
|
|
134
|
+
return redactor ? redactor.redact(value) : value;
|
|
135
|
+
if (!value || typeof value !== "object")
|
|
136
|
+
return value;
|
|
137
|
+
if (Array.isArray(value))
|
|
138
|
+
return value.map((item) => redactStrings(item, redactor));
|
|
139
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, redactStrings(item, redactor)]));
|
|
140
|
+
}
|
|
141
|
+
function deepFreeze(value) {
|
|
142
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
143
|
+
Object.freeze(value);
|
|
144
|
+
for (const item of Object.values(value))
|
|
145
|
+
deepFreeze(item);
|
|
146
|
+
}
|
|
147
|
+
return value;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=run-bundle.js.map
|
package/dist/secure-agent.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { Agent, SecureAgentOptions } from "./contracts.js";
|
|
2
|
+
import { assertHostCompositionReadiness, HostCompositionError, type HostCompositionGovernance, type HostCompositionOptions, type HostCompositionProfile, type HostCompositionReport, type HostCompositionToolReport, inspectHostComposition } from "./host-composition.js";
|
|
3
|
+
export { assertHostCompositionReadiness, HostCompositionError, type HostCompositionGovernance, type HostCompositionOptions, type HostCompositionProfile, type HostCompositionReport, type HostCompositionToolReport, inspectHostComposition, };
|
|
2
4
|
/** Build an opt-in agent whose security-critical defaults cannot be replaced per run. */
|
|
3
5
|
export declare function createSecureAgent(options: SecureAgentOptions): Agent;
|
package/dist/secure-agent.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { validateRunStateOptions } from "./agent-run-state.js";
|
|
2
2
|
import { createAgent } from "./agents.js";
|
|
3
|
+
import { assertHostCompositionReadiness, HostCompositionError, inspectHostComposition, } from "./host-composition.js";
|
|
3
4
|
import { assertIdentityActive, assertIdentityMatchesOwnership } from "./identity.js";
|
|
4
5
|
import { resolveRunLimits } from "./run-limits.js";
|
|
5
6
|
import { createToolParameterValidator, createToolRegistry } from "./tools.js";
|
|
7
|
+
export { assertHostCompositionReadiness, HostCompositionError, inspectHostComposition, };
|
|
6
8
|
/** Build an opt-in agent whose security-critical defaults cannot be replaced per run. */
|
|
7
9
|
export function createSecureAgent(options) {
|
|
8
10
|
if (!options.id.trim())
|
|
@@ -32,6 +34,9 @@ export function createSecureAgent(options) {
|
|
|
32
34
|
assertIdentityActive(options.identity);
|
|
33
35
|
assertIdentityMatchesOwnership(options.identity, options.ownership);
|
|
34
36
|
}
|
|
37
|
+
if (options.composition) {
|
|
38
|
+
assertHostCompositionReadiness({ ...options.composition, agent: options });
|
|
39
|
+
}
|
|
35
40
|
const runState = Object.freeze({ ...options.runState, definitionRevision: options.definitionRevision, interruptBeforeTool: true });
|
|
36
41
|
validateRunStateOptions(runState);
|
|
37
42
|
const config = Object.freeze({
|
|
@@ -52,7 +57,7 @@ export function createSecureAgent(options) {
|
|
|
52
57
|
return createAgent(config);
|
|
53
58
|
}
|
|
54
59
|
function withoutSecureFields(options) {
|
|
55
|
-
const { tools: _tools, toolArgumentValidator: _validator, redactor: _redactor, permission: _permission, trust: _trust, ownership: _ownership, identity: _identity, limits: _limits, guardrails: _guardrails, definitionRevision: _revision, runState: _runState, ...config } = options;
|
|
60
|
+
const { tools: _tools, toolArgumentValidator: _validator, redactor: _redactor, permission: _permission, trust: _trust, ownership: _ownership, identity: _identity, limits: _limits, guardrails: _guardrails, definitionRevision: _revision, runState: _runState, composition: _composition, ...config } = options;
|
|
56
61
|
return config;
|
|
57
62
|
}
|
|
58
63
|
function freezeGuardrails(guardrails) {
|
|
@@ -68,7 +68,11 @@ async function checkpointCasProbe(checkpoints) {
|
|
|
68
68
|
const loaded = await checkpoints.loadCheckpoint(key);
|
|
69
69
|
assert.equal(loaded?.version, 4, "winning version must persist");
|
|
70
70
|
assert.equal(loaded?.fencingToken, 6, "winning fence must persist");
|
|
71
|
-
|
|
71
|
+
const foreign = await checkpoints.loadCheckpoint({ ...key, tenantId: "tenant-b" });
|
|
72
|
+
assert.equal(foreign, null, "a foreign checkpoint lands as a miss, not an ownership-shaped existence oracle");
|
|
73
|
+
await assertRejectsCode(() => checkpoints.saveCheckpoint({ ...key, tenantId: "tenant-b", version: 99, expectedVersion: 0, value: { evil: true } }), "ERR_PRISM_CHECKPOINT_CONFLICT", "a foreign checkpoint save must fail closed as a CAS conflict");
|
|
74
|
+
const intact = await checkpoints.loadCheckpoint(key);
|
|
75
|
+
assert.equal(intact?.version, 4, "a foreign writer must not disturb the owner's record");
|
|
72
76
|
}
|
|
73
77
|
/**
|
|
74
78
|
* Approval determinism: concurrent approve/deny of the same pending decision
|
|
@@ -334,15 +338,4 @@ async function assertRejectsCode(action, code, message) {
|
|
|
334
338
|
}
|
|
335
339
|
throw new Error(`${message}; expected a rejection with code ${code}`);
|
|
336
340
|
}
|
|
337
|
-
async function assertRejects(action, pattern, message) {
|
|
338
|
-
try {
|
|
339
|
-
await action();
|
|
340
|
-
}
|
|
341
|
-
catch (error) {
|
|
342
|
-
if (pattern.test(String(error)))
|
|
343
|
-
return;
|
|
344
|
-
throw new Error(`${message}; rejection did not match ${pattern}: ${String(error)}`);
|
|
345
|
-
}
|
|
346
|
-
throw new Error(`${message}; expected a rejection matching ${pattern}`);
|
|
347
|
-
}
|
|
348
341
|
//# sourceMappingURL=state-concurrency-conformance.js.map
|
|
@@ -38,3 +38,15 @@ export declare function foldToolResultHistory(history: readonly Message[], optio
|
|
|
38
38
|
export declare function foldToolResults(results: readonly ToolResult[], options: ResolvedToolResultFoldOptions, context: FoldToolResultsContext): Promise<readonly ToolResult[]>;
|
|
39
39
|
export declare function formatFoldedToolResult(summary: string): string;
|
|
40
40
|
export declare function foldedToolResultHeader(toolName: string, toolCallId: string, summary: string): string;
|
|
41
|
+
/** Text the fold summarizes for one tool result: the payload JSON, then any text blocks.
|
|
42
|
+
* Shared with the attention compiler so both hash/summarize the same bytes. */
|
|
43
|
+
export declare function toolResultFoldText(result: unknown, error: unknown, extra?: readonly {
|
|
44
|
+
readonly type: string;
|
|
45
|
+
}[]): string;
|
|
46
|
+
/** UTF-8 cap that never splits a multi-byte character. Shared with the attention
|
|
47
|
+
* compiler's host-summarize path so both cap host text identically. */
|
|
48
|
+
export declare function capToolResultSummary(summary: string, maxBytes: number): string;
|
|
49
|
+
/** Provider turn per history index: assistant messages advance the turn, tool rows use
|
|
50
|
+
* their `prismToolResultTurn` stamp when present and the last assistant turn otherwise.
|
|
51
|
+
* Shared with the attention compiler so age gates match the fold exactly. */
|
|
52
|
+
export declare function inferToolResultTurns(history: readonly Message[]): readonly number[];
|