@pikku/core 0.12.107 → 0.12.112
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 +357 -0
- package/dist/analytics/analytics.d.ts +6 -0
- package/dist/analytics/analytics.js +58 -0
- package/dist/analytics/analytics.types.d.ts +156 -0
- package/dist/analytics/analytics.types.js +1 -0
- package/dist/analytics/anonymous-analytics-identity.d.ts +23 -0
- package/dist/analytics/anonymous-analytics-identity.js +27 -0
- package/dist/analytics/compose-analytics-identity.d.ts +14 -0
- package/dist/analytics/compose-analytics-identity.js +33 -0
- package/dist/analytics/cookie-analytics-identity.d.ts +24 -0
- package/dist/analytics/cookie-analytics-identity.js +37 -0
- package/dist/analytics/define-analytics-events.d.ts +22 -0
- package/dist/analytics/define-analytics-events.js +9 -0
- package/dist/analytics/fan-out-analytics.d.ts +15 -0
- package/dist/analytics/fan-out-analytics.js +36 -0
- package/dist/analytics/index.d.ts +13 -0
- package/dist/analytics/index.js +8 -0
- package/dist/analytics/logger-analytics-service.d.ts +14 -0
- package/dist/analytics/logger-analytics-service.js +23 -0
- package/dist/analytics/mint-cookie.d.ts +44 -0
- package/dist/analytics/mint-cookie.js +55 -0
- package/dist/dev/hot-reload.d.ts +0 -1
- package/dist/dev/hot-reload.js +4 -25
- package/dist/dev/module-runner.js +104 -25
- package/dist/errors/errors.d.ts +7 -0
- package/dist/errors/errors.js +17 -0
- package/dist/function/function-meta.types.d.ts +2 -0
- package/dist/function/function-runner.js +29 -0
- package/dist/function/functions.types.d.ts +22 -3
- package/dist/middleware/auth-apikey.d.ts +1 -1
- package/dist/pikku-state.d.ts +1 -1
- package/dist/scopes.d.ts +11 -0
- package/dist/scopes.js +17 -0
- package/dist/services/credential-wire-service.d.ts +1 -1
- package/dist/services/feature-flag-service.d.ts +100 -0
- package/dist/services/feature-flag-service.js +1 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/meta-service.d.ts +16 -0
- package/dist/services/meta-service.js +19 -0
- package/dist/services/webhook-service.d.ts +7 -2
- package/dist/services/webhook-service.js +11 -6
- package/dist/testing/service-tests/agent-run-service-tests.d.ts +2 -2
- package/dist/testing/service-tests/agent-storage-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/channel-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/credential-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/deployment-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/event-hub-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/secret-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/session-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/workflow-run-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/workflow-service-tests.d.ts +1 -1
- package/dist/types/core.types.d.ts +23 -0
- package/dist/wirings/agent/agent-rpc.d.ts +1 -1
- package/dist/wirings/agent/agent-turn.d.ts +1 -1
- package/dist/wirings/agent-scorer/agent-scorer-live.d.ts +1 -1
- package/dist/wirings/channel/channel-common.d.ts +1 -1
- package/dist/wirings/channel/channel-rpc-validators.d.ts +2 -2
- package/dist/wirings/channel/channel-runner.d.ts +1 -1
- package/dist/wirings/channel/local/local-channel-runner.d.ts +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +1 -1
- package/dist/wirings/cli/channel/cli-approval.d.ts +2 -2
- package/dist/wirings/flag/assert-feature-available.d.ts +15 -0
- package/dist/wirings/flag/assert-feature-available.js +23 -0
- package/dist/wirings/flag/cached-flag-source.d.ts +73 -0
- package/dist/wirings/flag/cached-flag-source.js +96 -0
- package/dist/wirings/flag/define-feature-flags.d.ts +33 -0
- package/dist/wirings/flag/define-feature-flags.js +32 -0
- package/dist/wirings/flag/flag.types.d.ts +97 -0
- package/dist/wirings/flag/flag.types.js +1 -0
- package/dist/wirings/flag/index.d.ts +7 -0
- package/dist/wirings/flag/index.js +5 -0
- package/dist/wirings/flag/resolve-flag.d.ts +52 -0
- package/dist/wirings/flag/resolve-flag.js +90 -0
- package/dist/wirings/flag/validate-flag-definitions.d.ts +26 -0
- package/dist/wirings/flag/validate-flag-definitions.js +103 -0
- package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +8 -8
- package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +1 -1
- package/dist/wirings/workflow/workflow-queue-routing.d.ts +1 -1
- package/knowledge/decisions/internals/a-reset-suite-makes-the-dev-seed-the-fixture.md +50 -0
- package/knowledge/decisions/internals/hot-reload-reads-the-changed-source-never-a-compiled-copy.md +38 -0
- package/knowledge/decisions/internals/index.md +2 -0
- package/package.json +11 -5
- package/run-tests.sh +17 -9
- package/src/public-surface.json +26 -0
- package/src/agent-naming.test.ts +0 -68
- package/src/api-report.test.ts +0 -138
- package/src/app-alias-surface.test.ts +0 -179
- package/src/app-leaf-surface.test.ts +0 -222
- package/src/bootstrap-compat/root.ts +0 -20
- package/src/classification/column-form.test.ts +0 -97
- package/src/classification/column-form.ts +0 -55
- package/src/classification/data-classification.ts +0 -73
- package/src/classification/index.ts +0 -40
- package/src/classification/key-ids.ts +0 -2
- package/src/classification/secret-value.test.ts +0 -204
- package/src/classification/secret-value.ts +0 -106
- package/src/crypto-utils.test.ts +0 -668
- package/src/crypto-utils.ts +0 -460
- package/src/dev/hot-reload.test.ts +0 -587
- package/src/dev/hot-reload.ts +0 -225
- package/src/dev/module-runner.test.ts +0 -235
- package/src/dev/module-runner.ts +0 -138
- package/src/dev/reload-meta.test.ts +0 -183
- package/src/dev/reload-meta.ts +0 -144
- package/src/ecosystem-tier-removed.test.ts +0 -72
- package/src/env.ts +0 -1
- package/src/errors/error-handler.ts +0 -77
- package/src/errors/error.test.ts +0 -229
- package/src/errors/errors.ts +0 -393
- package/src/errors/index.ts +0 -11
- package/src/errors/serialized-error.ts +0 -12
- package/src/factory-functions.test.ts +0 -111
- package/src/function/abort-scope.test.ts +0 -97
- package/src/function/abort-scope.ts +0 -80
- package/src/function/function-meta.types.ts +0 -151
- package/src/function/function-runner.test.ts +0 -1619
- package/src/function/function-runner.ts +0 -499
- package/src/function/functions.types.ts +0 -319
- package/src/function/index.ts +0 -40
- package/src/function/list.types.test.ts +0 -100
- package/src/function/list.types.ts +0 -69
- package/src/function/pikku-request.test.ts +0 -35
- package/src/function/pikku-request.ts +0 -17
- package/src/gopass-secrets-removed.test.ts +0 -51
- package/src/handle-error.test.ts +0 -532
- package/src/handle-error.ts +0 -64
- package/src/middleware/auth-apikey.test.ts +0 -362
- package/src/middleware/auth-apikey.ts +0 -39
- package/src/middleware/auth-bearer.test.ts +0 -566
- package/src/middleware/auth-bearer.ts +0 -83
- package/src/middleware/auth-cookie.test.ts +0 -572
- package/src/middleware/auth-cookie.ts +0 -107
- package/src/middleware/cors.test.ts +0 -579
- package/src/middleware/cors.ts +0 -103
- package/src/middleware/index.ts +0 -30
- package/src/middleware/middleware-factories.ts +0 -76
- package/src/middleware/middleware.types.ts +0 -61
- package/src/middleware/remote-auth.test.ts +0 -547
- package/src/middleware/remote-auth.ts +0 -95
- package/src/middleware/remote-jobs-secret.ts +0 -35
- package/src/middleware/require-origin.test.ts +0 -115
- package/src/middleware/require-origin.ts +0 -79
- package/src/middleware/telemetry.ts +0 -83
- package/src/middleware-runner.test.ts +0 -578
- package/src/middleware-runner.ts +0 -232
- package/src/no-any-casts.test.ts +0 -57
- package/src/no-root-barrel.test.ts +0 -122
- package/src/permissions.test.ts +0 -256
- package/src/permissions.ts +0 -217
- package/src/pikku-state.test.ts +0 -198
- package/src/pikku-state.ts +0 -206
- package/src/production-barrels-stay-lean.test.ts +0 -110
- package/src/public-surface.test.ts +0 -133
- package/src/remote.test.ts +0 -173
- package/src/remote.ts +0 -56
- package/src/removed-legacy-exports.test.ts +0 -66
- package/src/run-tests-script.test.ts +0 -67
- package/src/schema.test.ts +0 -430
- package/src/schema.ts +0 -204
- package/src/scopes.test.ts +0 -203
- package/src/scopes.ts +0 -67
- package/src/services/agent-run-state-service.ts +0 -37
- package/src/services/agent-runner-service.ts +0 -238
- package/src/services/agent-storage-service.ts +0 -39
- package/src/services/ai-embedding-service.ts +0 -9
- package/src/services/audit-service.test.ts +0 -44
- package/src/services/audit-service.ts +0 -280
- package/src/services/content-service.ts +0 -65
- package/src/services/credential-service.ts +0 -20
- package/src/services/credential-wire-service.test.ts +0 -235
- package/src/services/credential-wire-service.ts +0 -120
- package/src/services/deployment-service.ts +0 -32
- package/src/services/email-service.test.ts +0 -100
- package/src/services/email-service.ts +0 -60
- package/src/services/email-template.test.ts +0 -311
- package/src/services/email-template.ts +0 -254
- package/src/services/file-scenario-run-store.test.ts +0 -349
- package/src/services/file-scenario-run-store.ts +0 -282
- package/src/services/gateway-service.ts +0 -5
- package/src/services/http-personas-converse.test.ts +0 -274
- package/src/services/http-personas.test.ts +0 -379
- package/src/services/http-personas.ts +0 -508
- package/src/services/in-memory-agent-run-state-service.ts +0 -87
- package/src/services/in-memory-queue-service.test.ts +0 -162
- package/src/services/in-memory-queue-service.ts +0 -78
- package/src/services/in-memory-session-store.test.ts +0 -58
- package/src/services/in-memory-session-store.ts +0 -20
- package/src/services/in-memory-trigger-service.ts +0 -47
- package/src/services/in-memory-workflow-service.test.ts +0 -430
- package/src/services/in-memory-workflow-service.ts +0 -595
- package/src/services/index.ts +0 -192
- package/src/services/istanbul-coverage-service.test.ts +0 -66
- package/src/services/istanbul-coverage-service.ts +0 -59
- package/src/services/jwt-service.ts +0 -15
- package/src/services/local-content-request-handler.test.ts +0 -240
- package/src/services/local-content-request-handler.ts +0 -295
- package/src/services/local-content.test.ts +0 -186
- package/src/services/local-content.ts +0 -242
- package/src/services/local-credential-service.ts +0 -63
- package/src/services/local-email-service.test.ts +0 -182
- package/src/services/local-email-service.ts +0 -43
- package/src/services/local-gateway-service.ts +0 -51
- package/src/services/local-secrets.test.ts +0 -95
- package/src/services/local-secrets.ts +0 -71
- package/src/services/local-variables.test.ts +0 -61
- package/src/services/local-variables.ts +0 -45
- package/src/services/logger-console.test.ts +0 -117
- package/src/services/logger-console.ts +0 -174
- package/src/services/logger.ts +0 -48
- package/src/services/meta-service.test.ts +0 -75
- package/src/services/meta-service.ts +0 -767
- package/src/services/persona-actor-secret.test.ts +0 -68
- package/src/services/persona-actor-secret.ts +0 -70
- package/src/services/persona-sign-in.test.ts +0 -219
- package/src/services/persona-sign-in.ts +0 -238
- package/src/services/personas-service.ts +0 -191
- package/src/services/pikku-user-id.test.ts +0 -62
- package/src/services/pikku-user-id.ts +0 -13
- package/src/services/queue-webhook-service.test.ts +0 -409
- package/src/services/queue-webhook-service.ts +0 -150
- package/src/services/remote-jobs.test.ts +0 -106
- package/src/services/remote-jobs.ts +0 -92
- package/src/services/scheduler-service.ts +0 -37
- package/src/services/schema-service.ts +0 -10
- package/src/services/scope-service.ts +0 -91
- package/src/services/scoped-credential-service.test.ts +0 -86
- package/src/services/scoped-credential-service.ts +0 -63
- package/src/services/scoped-secret-service.test.ts +0 -93
- package/src/services/scoped-secret-service.ts +0 -40
- package/src/services/secret-host-binding.test.ts +0 -138
- package/src/services/secret-host-binding.ts +0 -51
- package/src/services/secret-service.ts +0 -25
- package/src/services/secretless.test.ts +0 -54
- package/src/services/secretless.ts +0 -29
- package/src/services/session-store.ts +0 -9
- package/src/services/stub-tracker.test.ts +0 -104
- package/src/services/stub-tracker.ts +0 -175
- package/src/services/system-role-guard.test.ts +0 -96
- package/src/services/system-role-guard.ts +0 -71
- package/src/services/temporary-file-service.ts +0 -76
- package/src/services/trigger-service.ts +0 -5
- package/src/services/typed-credential-service.ts +0 -83
- package/src/services/typed-secret-service.test.ts +0 -204
- package/src/services/typed-secret-service.ts +0 -132
- package/src/services/typed-variables-service.test.ts +0 -166
- package/src/services/typed-variables-service.ts +0 -166
- package/src/services/user-session-service.test.ts +0 -147
- package/src/services/user-session-service.ts +0 -85
- package/src/services/v8-coverage-service.test.ts +0 -69
- package/src/services/v8-coverage-service.ts +0 -163
- package/src/services/variables-service.ts +0 -13
- package/src/services/webhook-service.ts +0 -147
- package/src/services/workflow-service.ts +0 -120
- package/src/side-effects-are-declared.test.ts +0 -84
- package/src/source-files-stay-composable.test.ts +0 -41
- package/src/template-alias-surface.test.ts +0 -240
- package/src/test-utils.ts +0 -38
- package/src/testing/index.ts +0 -3
- package/src/testing/service-tests/agent-run-service-tests.ts +0 -98
- package/src/testing/service-tests/agent-storage-service-tests.ts +0 -379
- package/src/testing/service-tests/channel-store-tests.ts +0 -98
- package/src/testing/service-tests/credential-service-tests.ts +0 -143
- package/src/testing/service-tests/deployment-service-tests.ts +0 -33
- package/src/testing/service-tests/event-hub-store-tests.ts +0 -48
- package/src/testing/service-tests/secret-service-tests.ts +0 -105
- package/src/testing/service-tests/session-store-tests.ts +0 -62
- package/src/testing/service-tests/workflow-run-service-tests.ts +0 -59
- package/src/testing/service-tests/workflow-service-tests.ts +0 -308
- package/src/testing/service-tests.ts +0 -95
- package/src/time-utils.test.ts +0 -56
- package/src/time-utils.ts +0 -89
- package/src/types/core.types.ts +0 -446
- package/src/types/index.ts +0 -25
- package/src/types/state.types.ts +0 -226
- package/src/types/typed-credentials.test.ts +0 -72
- package/src/utils/hash.test.ts +0 -68
- package/src/utils/hash.ts +0 -26
- package/src/utils/hmac.ts +0 -21
- package/src/utils/node-host-resolver.ts +0 -20
- package/src/utils/safe-fetch.test.ts +0 -515
- package/src/utils/safe-fetch.ts +0 -347
- package/src/utils.test.ts +0 -359
- package/src/utils.ts +0 -165
- package/src/version.test.ts +0 -80
- package/src/version.ts +0 -25
- package/src/wirings/actor-flow/actor-flow.types.ts +0 -40
- package/src/wirings/actor-flow/index.ts +0 -10
- package/src/wirings/actor-flow/run-conversation.test.ts +0 -187
- package/src/wirings/actor-flow/run-conversation.ts +0 -280
- package/src/wirings/addon/addon-auth-tags.test.ts +0 -219
- package/src/wirings/addon/addon-runner.ts +0 -236
- package/src/wirings/addon/addon-scopes.test.ts +0 -225
- package/src/wirings/addon/addon-secrets.test.ts +0 -391
- package/src/wirings/addon/index.ts +0 -12
- package/src/wirings/addon/remote-addon-auth.ts +0 -65
- package/src/wirings/addon/wire-addon.test.ts +0 -102
- package/src/wirings/addon/wire-addon.ts +0 -202
- package/src/wirings/addon/wire-remote-addon.ts +0 -41
- package/src/wirings/agent/agent-agui.test.ts +0 -1213
- package/src/wirings/agent/agent-agui.ts +0 -405
- package/src/wirings/agent/agent-authorization.test.ts +0 -208
- package/src/wirings/agent/agent-finalize.test.ts +0 -187
- package/src/wirings/agent/agent-finalize.ts +0 -197
- package/src/wirings/agent/agent-helpers.test.ts +0 -215
- package/src/wirings/agent/agent-helpers.ts +0 -96
- package/src/wirings/agent/agent-interrupt.test.ts +0 -833
- package/src/wirings/agent/agent-interrupt.ts +0 -400
- package/src/wirings/agent/agent-memory.test.ts +0 -397
- package/src/wirings/agent/agent-memory.ts +0 -496
- package/src/wirings/agent/agent-middleware.types.test.ts +0 -41
- package/src/wirings/agent/agent-model-config.test.ts +0 -103
- package/src/wirings/agent/agent-model-config.ts +0 -59
- package/src/wirings/agent/agent-prepare.test.ts +0 -977
- package/src/wirings/agent/agent-prepare.ts +0 -1083
- package/src/wirings/agent/agent-registry.test.ts +0 -455
- package/src/wirings/agent/agent-registry.ts +0 -99
- package/src/wirings/agent/agent-resume-authorization.test.ts +0 -206
- package/src/wirings/agent/agent-rpc.ts +0 -116
- package/src/wirings/agent/agent-runner.test.ts +0 -1229
- package/src/wirings/agent/agent-runner.ts +0 -858
- package/src/wirings/agent/agent-stream-delegate.test.ts +0 -381
- package/src/wirings/agent/agent-stream-output-hooks.test.ts +0 -353
- package/src/wirings/agent/agent-stream.test.ts +0 -1800
- package/src/wirings/agent/agent-stream.ts +0 -1639
- package/src/wirings/agent/agent-thread-ownership.test.ts +0 -297
- package/src/wirings/agent/agent-turn.test.ts +0 -65
- package/src/wirings/agent/agent-turn.ts +0 -122
- package/src/wirings/agent/agent-utils.ts +0 -20
- package/src/wirings/agent/agent.types.ts +0 -676
- package/src/wirings/agent/index.ts +0 -58
- package/src/wirings/agent/voice-input.test.ts +0 -220
- package/src/wirings/agent/voice-input.ts +0 -180
- package/src/wirings/agent/voice-output.test.ts +0 -510
- package/src/wirings/agent/voice-output.ts +0 -311
- package/src/wirings/agent-scorer/agent-scorer-grade.test.ts +0 -106
- package/src/wirings/agent-scorer/agent-scorer-grade.ts +0 -55
- package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +0 -285
- package/src/wirings/agent-scorer/agent-scorer-judge.ts +0 -180
- package/src/wirings/agent-scorer/agent-scorer-live.test.ts +0 -174
- package/src/wirings/agent-scorer/agent-scorer-live.ts +0 -56
- package/src/wirings/agent-scorer/agent-scorer-registry.ts +0 -66
- package/src/wirings/agent-scorer/agent-scorer-sampling.test.ts +0 -34
- package/src/wirings/agent-scorer/agent-scorer-sampling.ts +0 -36
- package/src/wirings/agent-scorer/agent-scorer-snapshots.test.ts +0 -49
- package/src/wirings/agent-scorer/agent-scorer-snapshots.ts +0 -46
- package/src/wirings/agent-scorer/agent-scorer-worker.test.ts +0 -122
- package/src/wirings/agent-scorer/agent-scorer-worker.ts +0 -71
- package/src/wirings/agent-scorer/agent-scorer.ts +0 -102
- package/src/wirings/agent-scorer/agent-scorer.types.ts +0 -128
- package/src/wirings/agent-scorer/index.ts +0 -23
- package/src/wirings/channel/channel-common.ts +0 -102
- package/src/wirings/channel/channel-handler-shapes.test.ts +0 -72
- package/src/wirings/channel/channel-handler.test.ts +0 -322
- package/src/wirings/channel/channel-handler.ts +0 -259
- package/src/wirings/channel/channel-host-rpc.test.ts +0 -150
- package/src/wirings/channel/channel-host-rpc.ts +0 -69
- package/src/wirings/channel/channel-middleware-runner.test.ts +0 -188
- package/src/wirings/channel/channel-middleware-runner.ts +0 -126
- package/src/wirings/channel/channel-rpc-registry.ts +0 -116
- package/src/wirings/channel/channel-rpc-responder.ts +0 -117
- package/src/wirings/channel/channel-rpc-service.ts +0 -132
- package/src/wirings/channel/channel-rpc-validators.ts +0 -65
- package/src/wirings/channel/channel-rpc.test.ts +0 -841
- package/src/wirings/channel/channel-rpc.ts +0 -5
- package/src/wirings/channel/channel-rpc.types.ts +0 -160
- package/src/wirings/channel/channel-runner.ts +0 -164
- package/src/wirings/channel/channel-store.ts +0 -35
- package/src/wirings/channel/channel.types.ts +0 -193
- package/src/wirings/channel/define-channel-routes.ts +0 -5
- package/src/wirings/channel/eventhub-service.ts +0 -16
- package/src/wirings/channel/eventhub-store.ts +0 -13
- package/src/wirings/channel/index.ts +0 -40
- package/src/wirings/channel/local/index.ts +0 -3
- package/src/wirings/channel/local/local-channel-handler.ts +0 -98
- package/src/wirings/channel/local/local-channel-runner.test.ts +0 -339
- package/src/wirings/channel/local/local-channel-runner.ts +0 -271
- package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -77
- package/src/wirings/channel/local/local-eventhub-service.ts +0 -69
- package/src/wirings/channel/log-channels.ts +0 -16
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +0 -135
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +0 -60
- package/src/wirings/channel/serverless/index.ts +0 -6
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +0 -328
- package/src/wirings/cli/channel/cli-approval.test.ts +0 -177
- package/src/wirings/cli/channel/cli-approval.ts +0 -135
- package/src/wirings/cli/channel/cli-channel-runner.ts +0 -118
- package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +0 -192
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +0 -148
- package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +0 -480
- package/src/wirings/cli/channel/cli-raw-client-runner.ts +0 -188
- package/src/wirings/cli/channel/index.ts +0 -6
- package/src/wirings/cli/cli-runner.test.ts +0 -969
- package/src/wirings/cli/cli-runner.ts +0 -538
- package/src/wirings/cli/cli.types.ts +0 -388
- package/src/wirings/cli/command-parser.test.ts +0 -1120
- package/src/wirings/cli/command-parser.ts +0 -713
- package/src/wirings/cli/define-cli-commands.ts +0 -13
- package/src/wirings/cli/format-cli-error.test.ts +0 -91
- package/src/wirings/cli/format-cli-error.ts +0 -96
- package/src/wirings/cli/index.ts +0 -19
- package/src/wirings/credential/credential.types.ts +0 -37
- package/src/wirings/credential/define-credential.ts +0 -49
- package/src/wirings/credential/index.ts +0 -7
- package/src/wirings/credential/validate-credential-definitions.ts +0 -63
- package/src/wirings/gateway/gateway-authorization.test.ts +0 -575
- package/src/wirings/gateway/gateway-channel-meta.test.ts +0 -44
- package/src/wirings/gateway/gateway-runner.test.ts +0 -581
- package/src/wirings/gateway/gateway-runner.ts +0 -411
- package/src/wirings/gateway/gateway.types.ts +0 -137
- package/src/wirings/gateway/index.ts +0 -15
- package/src/wirings/http/http-routes.test.ts +0 -318
- package/src/wirings/http/http-routes.ts +0 -111
- package/src/wirings/http/http-runner-addon-ref.test.ts +0 -238
- package/src/wirings/http/http-runner.test.ts +0 -503
- package/src/wirings/http/http-runner.ts +0 -462
- package/src/wirings/http/http.types.ts +0 -307
- package/src/wirings/http/index.ts +0 -27
- package/src/wirings/http/log-http-routes.ts +0 -18
- package/src/wirings/http/pikku-fetch-http-request.test.ts +0 -318
- package/src/wirings/http/pikku-fetch-http-request.ts +0 -260
- package/src/wirings/http/pikku-fetch-http-response.test.ts +0 -123
- package/src/wirings/http/pikku-fetch-http-response.ts +0 -149
- package/src/wirings/http/routers/http-router.ts +0 -13
- package/src/wirings/http/routers/path-to-regex.test.ts +0 -306
- package/src/wirings/http/routers/path-to-regex.ts +0 -115
- package/src/wirings/http/web-request.test.ts +0 -382
- package/src/wirings/http/web-request.ts +0 -162
- package/src/wirings/mcp/index.ts +0 -26
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -388
- package/src/wirings/mcp/mcp-endpoint-registry.ts +0 -159
- package/src/wirings/mcp/mcp-runner.test.ts +0 -588
- package/src/wirings/mcp/mcp-runner.ts +0 -330
- package/src/wirings/mcp/mcp.types.ts +0 -199
- package/src/wirings/node/index.ts +0 -2
- package/src/wirings/node/node.types.ts +0 -23
- package/src/wirings/oauth2/index.ts +0 -1
- package/src/wirings/oauth2/oauth2.types.ts +0 -12
- package/src/wirings/persona/define-personas.ts +0 -33
- package/src/wirings/persona/index.ts +0 -75
- package/src/wirings/persona/persona-app-scopes.test.ts +0 -47
- package/src/wirings/persona/persona-app-scopes.ts +0 -74
- package/src/wirings/persona/persona-email.ts +0 -87
- package/src/wirings/persona/persona-environments.test.ts +0 -194
- package/src/wirings/persona/persona-environments.ts +0 -138
- package/src/wirings/persona/persona-mailbox.ts +0 -156
- package/src/wirings/persona/persona.test.ts +0 -230
- package/src/wirings/persona/persona.types.ts +0 -156
- package/src/wirings/persona/validate-personas.ts +0 -137
- package/src/wirings/queue/index.ts +0 -29
- package/src/wirings/queue/queue-identity.test.ts +0 -454
- package/src/wirings/queue/queue-identity.ts +0 -176
- package/src/wirings/queue/queue-runner.test.ts +0 -705
- package/src/wirings/queue/queue-runner.ts +0 -181
- package/src/wirings/queue/queue.types.ts +0 -161
- package/src/wirings/queue/register-queue-helper.ts +0 -46
- package/src/wirings/queue/signed-queue-service.ts +0 -60
- package/src/wirings/queue/validate-worker-config.test.ts +0 -108
- package/src/wirings/queue/validate-worker-config.ts +0 -90
- package/src/wirings/role/define-system-role.ts +0 -33
- package/src/wirings/role/index.ts +0 -13
- package/src/wirings/role/role.test.ts +0 -104
- package/src/wirings/role/role.types.ts +0 -47
- package/src/wirings/role/validate-role-definitions.ts +0 -93
- package/src/wirings/rpc/index.ts +0 -8
- package/src/wirings/rpc/rpc-runner.test.ts +0 -1130
- package/src/wirings/rpc/rpc-runner.ts +0 -569
- package/src/wirings/rpc/rpc-types.ts +0 -87
- package/src/wirings/scheduler/index.ts +0 -11
- package/src/wirings/scheduler/log-schedulers.ts +0 -16
- package/src/wirings/scheduler/scheduler-runner.test.ts +0 -835
- package/src/wirings/scheduler/scheduler-runner.ts +0 -138
- package/src/wirings/scheduler/scheduler.types.ts +0 -42
- package/src/wirings/scope/define-scope.ts +0 -33
- package/src/wirings/scope/index.ts +0 -15
- package/src/wirings/scope/scope.test.ts +0 -159
- package/src/wirings/scope/scope.types.ts +0 -42
- package/src/wirings/scope/validate-scope-definitions.ts +0 -107
- package/src/wirings/secret/index.ts +0 -9
- package/src/wirings/secret/secret.types.ts +0 -70
- package/src/wirings/secret/validate-secret-definitions.test.ts +0 -232
- package/src/wirings/secret/validate-secret-definitions.ts +0 -88
- package/src/wirings/trigger/index.ts +0 -9
- package/src/wirings/trigger/pikku-trigger-service.ts +0 -107
- package/src/wirings/trigger/trigger-runner.test.ts +0 -78
- package/src/wirings/trigger/trigger-runner.ts +0 -113
- package/src/wirings/trigger/trigger.types.ts +0 -100
- package/src/wirings/variable/index.ts +0 -8
- package/src/wirings/variable/validate-variable-definitions.test.ts +0 -115
- package/src/wirings/variable/validate-variable-definitions.ts +0 -71
- package/src/wirings/variable/variable.types.ts +0 -40
- package/src/wirings/virtual-user/index.ts +0 -107
- package/src/wirings/virtual-user/prepare-virtual-user-run.test.ts +0 -115
- package/src/wirings/virtual-user/prepare-virtual-user-run.ts +0 -95
- package/src/wirings/virtual-user/run-virtual-user.test.ts +0 -774
- package/src/wirings/virtual-user/run-virtual-user.ts +0 -684
- package/src/wirings/virtual-user/virtual-user-agents.test.ts +0 -72
- package/src/wirings/virtual-user/virtual-user-agents.ts +0 -62
- package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +0 -215
- package/src/wirings/virtual-user/virtual-user-catalogue.ts +0 -184
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +0 -426
- package/src/wirings/virtual-user/virtual-user-derive.ts +0 -161
- package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +0 -68
- package/src/wirings/virtual-user/virtual-user-dispositions.ts +0 -210
- package/src/wirings/virtual-user/virtual-user-intents.test.ts +0 -218
- package/src/wirings/virtual-user/virtual-user-intents.ts +0 -185
- package/src/wirings/virtual-user/virtual-user-rng.test.ts +0 -72
- package/src/wirings/virtual-user/virtual-user-rng.ts +0 -50
- package/src/wirings/virtual-user/virtual-user-run-store.ts +0 -131
- package/src/wirings/virtual-user/virtual-user-scaffold.test.ts +0 -854
- package/src/wirings/virtual-user/virtual-user-scaffold.ts +0 -664
- package/src/wirings/virtual-user/virtual-user-schedule-store.ts +0 -93
- package/src/wirings/virtual-user/virtual-user-schedule.test.ts +0 -280
- package/src/wirings/virtual-user/virtual-user-schedule.ts +0 -156
- package/src/wirings/virtual-user/virtual-user-target.ts +0 -47
- package/src/wirings/virtual-user/virtual-user.types.ts +0 -215
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +0 -709
- package/src/wirings/workflow/dsl/workflow-runner.ts +0 -25
- package/src/wirings/workflow/feature.test.ts +0 -131
- package/src/wirings/workflow/feature.ts +0 -59
- package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +0 -569
- package/src/wirings/workflow/graph/graph-foreach.test.ts +0 -626
- package/src/wirings/workflow/graph/graph-node.ts +0 -115
- package/src/wirings/workflow/graph/graph-runner.test.ts +0 -1049
- package/src/wirings/workflow/graph/graph-runner.ts +0 -1376
- package/src/wirings/workflow/graph/graph-validation.test.ts +0 -27
- package/src/wirings/workflow/graph/graph-validation.ts +0 -41
- package/src/wirings/workflow/graph/template.test.ts +0 -49
- package/src/wirings/workflow/graph/template.ts +0 -42
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -39
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -75
- package/src/wirings/workflow/index.ts +0 -107
- package/src/wirings/workflow/pikku-scenario-service.ts +0 -1013
- package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -963
- package/src/wirings/workflow/pikku-workflow-service.ts +0 -1993
- package/src/wirings/workflow/run-timeline.test.ts +0 -199
- package/src/wirings/workflow/run-timeline.ts +0 -185
- package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -107
- package/src/wirings/workflow/scenario-cookie-jar.ts +0 -57
- package/src/wirings/workflow/scenario-expectations.test.ts +0 -238
- package/src/wirings/workflow/scenario-hooks.test.ts +0 -259
- package/src/wirings/workflow/scenario-poll.test.ts +0 -64
- package/src/wirings/workflow/scenario-poll.ts +0 -27
- package/src/wirings/workflow/scenario-prose.test.ts +0 -275
- package/src/wirings/workflow/scenario-prose.ts +0 -86
- package/src/wirings/workflow/scenario-run.types.ts +0 -193
- package/src/wirings/workflow/scenario-service.test.ts +0 -147
- package/src/wirings/workflow/scenario-step-guards.ts +0 -23
- package/src/wirings/workflow/scenario-step.test.ts +0 -800
- package/src/wirings/workflow/scenario-step.types.ts +0 -262
- package/src/wirings/workflow/scenario-surface.test.ts +0 -146
- package/src/wirings/workflow/scenario-surface.ts +0 -71
- package/src/wirings/workflow/scenario.types.ts +0 -63
- package/src/wirings/workflow/workflow-approval-audit.ts +0 -47
- package/src/wirings/workflow/workflow-approval-policy.test.ts +0 -594
- package/src/wirings/workflow/workflow-approval-policy.ts +0 -68
- package/src/wirings/workflow/workflow-approval.ts +0 -290
- package/src/wirings/workflow/workflow-child-run-session.test.ts +0 -168
- package/src/wirings/workflow/workflow-constants.ts +0 -66
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +0 -116
- package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -55
- package/src/wirings/workflow/workflow-dispatch-relay.test.ts +0 -128
- package/src/wirings/workflow/workflow-errors.ts +0 -132
- package/src/wirings/workflow/workflow-inline-authority.test.ts +0 -175
- package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -51
- package/src/wirings/workflow/workflow-invocation-id.ts +0 -28
- package/src/wirings/workflow/workflow-meta-resolver.ts +0 -45
- package/src/wirings/workflow/workflow-mirror.test.ts +0 -171
- package/src/wirings/workflow/workflow-missing-meta.test.ts +0 -92
- package/src/wirings/workflow/workflow-on-error.test.ts +0 -145
- package/src/wirings/workflow/workflow-queue-routing.ts +0 -129
- package/src/wirings/workflow/workflow-queue-wiring.ts +0 -149
- package/src/wirings/workflow/workflow-queue-workers.test.ts +0 -131
- package/src/wirings/workflow/workflow-queue-workers.ts +0 -66
- package/src/wirings/workflow/workflow-recovery.ts +0 -192
- package/src/wirings/workflow/workflow-replay-snapshot.test.ts +0 -140
- package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -113
- package/src/wirings/workflow/workflow-run-authority.test.ts +0 -212
- package/src/wirings/workflow/workflow-run-context.test.ts +0 -172
- package/src/wirings/workflow/workflow-run-engine.types.ts +0 -92
- package/src/wirings/workflow/workflow-run-ownership.ts +0 -37
- package/src/wirings/workflow/workflow-run-polling.test.ts +0 -127
- package/src/wirings/workflow/workflow-stalled-recovery.test.ts +0 -152
- package/src/wirings/workflow/workflow-status-stream.test.ts +0 -354
- package/src/wirings/workflow/workflow-status-stream.ts +0 -144
- package/src/wirings/workflow/workflow-step-claim.ts +0 -46
- package/src/wirings/workflow/workflow-step-ordinal.test.ts +0 -94
- package/src/wirings/workflow/workflow-step-session.test.ts +0 -87
- package/src/wirings/workflow/workflow-suspend.ts +0 -61
- package/src/wirings/workflow/workflow-terminal-run-guard.test.ts +0 -105
- package/src/wirings/workflow/workflow.types.ts +0 -268
- package/src/wirings-stay-decoupled.test.ts +0 -130
- package/tsconfig.json +0 -14
- package/tsconfig.tsbuildinfo +0 -1
- package/tsconfig.type-tests.json +0 -15
|
@@ -1,1083 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
PikkuRawWire,
|
|
3
|
-
CoreUserSession,
|
|
4
|
-
GetCredential,
|
|
5
|
-
} from '../../types/core.types.js'
|
|
6
|
-
import type {
|
|
7
|
-
CoreAgent,
|
|
8
|
-
AgentInput,
|
|
9
|
-
AgentToolDef,
|
|
10
|
-
AgentContentPart,
|
|
11
|
-
AgentMessage,
|
|
12
|
-
AgentStreamChannel,
|
|
13
|
-
AgentStreamEvent,
|
|
14
|
-
PikkuAgentMiddlewareHooks,
|
|
15
|
-
SessionScope,
|
|
16
|
-
} from './agent.types.js'
|
|
17
|
-
import type { AgentRunnerParams } from '../../services/agent-runner-service.js'
|
|
18
|
-
import { PikkuError } from '../../errors/error-handler.js'
|
|
19
|
-
import {
|
|
20
|
-
checkAuthPermissions,
|
|
21
|
-
runPermissions,
|
|
22
|
-
type PermissionWire,
|
|
23
|
-
} from '../../permissions.js'
|
|
24
|
-
import { AIProviderNotConfiguredError } from '../../errors/errors.js'
|
|
25
|
-
import { ForbiddenError, MissingSessionError } from '../../errors/errors.js'
|
|
26
|
-
import { verifyScopes } from '../../scopes.js'
|
|
27
|
-
import { pikkuState, getSingletonServices } from '../../pikku-state.js'
|
|
28
|
-
import { createMiddlewareSessionWireProps } from '../../services/user-session-service.js'
|
|
29
|
-
import type { SessionService } from '../../services/user-session-service.js'
|
|
30
|
-
import { randomUUID } from './agent-utils.js'
|
|
31
|
-
import { awaitPendingInterruptNote } from './agent-interrupt.js'
|
|
32
|
-
import { streamAgent } from './agent-stream.js'
|
|
33
|
-
import { runAgent } from './agent-runner.js'
|
|
34
|
-
import {
|
|
35
|
-
resolveNamespace,
|
|
36
|
-
ContextAwareRPCService,
|
|
37
|
-
} from '../../wirings/rpc/rpc-runner.js'
|
|
38
|
-
import { getOrCreatePackageSingletonServices } from '../../wirings/addon/addon-runner.js'
|
|
39
|
-
import {
|
|
40
|
-
resolveMemoryServices,
|
|
41
|
-
loadContextMessages,
|
|
42
|
-
trimMessages,
|
|
43
|
-
} from './agent-memory.js'
|
|
44
|
-
import { resolveModelConfig } from './agent-model-config.js'
|
|
45
|
-
|
|
46
|
-
export type RunAgentParams = {
|
|
47
|
-
sessionService?: SessionService<CoreUserSession>
|
|
48
|
-
/** Credential accessor for the current request — used to read per-user overrides (e.g. AI_API_KEY). */
|
|
49
|
-
getCredential?: GetCredential
|
|
50
|
-
/** Ephemeral owner identity minted for a sessionless request; never client-supplied, never reused across requests. */
|
|
51
|
-
anonymousOwnerResourceId?: string
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export function resolveSessionPrincipal(
|
|
55
|
-
params: RunAgentParams,
|
|
56
|
-
sessionScope: SessionScope | undefined
|
|
57
|
-
): string | undefined {
|
|
58
|
-
const session = params.sessionService?.get()
|
|
59
|
-
if ((sessionScope ?? 'user') === 'org') {
|
|
60
|
-
if (!session?.orgId) {
|
|
61
|
-
throw new ForbiddenError(
|
|
62
|
-
'This agent is org-scoped but the session has no organization'
|
|
63
|
-
)
|
|
64
|
-
}
|
|
65
|
-
return session.orgId
|
|
66
|
-
}
|
|
67
|
-
return session?.userId
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function resolveOwnerResourceId(
|
|
71
|
-
params: RunAgentParams,
|
|
72
|
-
sessionScope: SessionScope | undefined,
|
|
73
|
-
requestedResourceId: string
|
|
74
|
-
): string {
|
|
75
|
-
const principal = resolveSessionPrincipal(params, sessionScope)
|
|
76
|
-
|
|
77
|
-
if (!principal) {
|
|
78
|
-
params.anonymousOwnerResourceId ??= `anon-${randomUUID()}`
|
|
79
|
-
return params.anonymousOwnerResourceId
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (
|
|
83
|
-
requestedResourceId === principal ||
|
|
84
|
-
requestedResourceId.startsWith(`${principal}:`)
|
|
85
|
-
) {
|
|
86
|
-
return requestedResourceId
|
|
87
|
-
}
|
|
88
|
-
return `${principal}:${requestedResourceId}`
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export function assertResourcePrincipalOwner(
|
|
92
|
-
params: RunAgentParams,
|
|
93
|
-
sessionScope: SessionScope | undefined,
|
|
94
|
-
storedResourceId: string,
|
|
95
|
-
kind: 'thread' | 'run'
|
|
96
|
-
): void {
|
|
97
|
-
const principal = resolveSessionPrincipal(params, sessionScope)
|
|
98
|
-
if (!principal || !isOwnedByPrincipal(storedResourceId, principal)) {
|
|
99
|
-
throw new ForbiddenError(`Not authorized to access this ${kind}`)
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function agentSessionScope(agentName: string): SessionScope {
|
|
104
|
-
return resolveAgent(agentName).agent.sessionScope ?? 'user'
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function assertResourceOwner(
|
|
108
|
-
ownerResourceId: string,
|
|
109
|
-
storedResourceId: string,
|
|
110
|
-
kind: 'thread' | 'run'
|
|
111
|
-
): void {
|
|
112
|
-
if (storedResourceId !== ownerResourceId) {
|
|
113
|
-
throw new ForbiddenError(`Not authorized to access this ${kind}`)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export function sessionPrincipals(
|
|
118
|
-
session: { userId?: string; orgId?: string } | undefined
|
|
119
|
-
): string[] {
|
|
120
|
-
return [session?.userId, session?.orgId].filter(
|
|
121
|
-
(principal): principal is string => Boolean(principal)
|
|
122
|
-
)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export function isOwnedByPrincipal(
|
|
126
|
-
storedResourceId: string,
|
|
127
|
-
principal: string
|
|
128
|
-
): boolean {
|
|
129
|
-
return (
|
|
130
|
-
storedResourceId === principal ||
|
|
131
|
-
storedResourceId.startsWith(`${principal}:`)
|
|
132
|
-
)
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export function threadOwnerConstraint(
|
|
136
|
-
session: { userId?: string; orgId?: string } | undefined
|
|
137
|
-
): string[] {
|
|
138
|
-
return sessionPrincipals(session)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export function canAccessThread(
|
|
142
|
-
storedResourceId: string,
|
|
143
|
-
session: { userId?: string; orgId?: string } | undefined
|
|
144
|
-
): boolean {
|
|
145
|
-
const principals = sessionPrincipals(session)
|
|
146
|
-
if (principals.length === 0) return false
|
|
147
|
-
return principals.some((principal) =>
|
|
148
|
-
isOwnedByPrincipal(storedResourceId, principal)
|
|
149
|
-
)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* An agent call with the fields nobody supplied left out.
|
|
154
|
-
*
|
|
155
|
-
* Omitted rather than passed as `undefined`, because an explicit `undefined`
|
|
156
|
-
* overrides the agent's own declared default with nothing — a request that
|
|
157
|
-
* names no model would silently unset the one the agent declares.
|
|
158
|
-
*
|
|
159
|
-
* Shared by the scaffolded `run` and `stream` routes, which receive the same
|
|
160
|
-
* input and differ only in what they do with the reply. `agentName` is not part
|
|
161
|
-
* of it: both callers pass that separately, because `rpc.agent.run` and
|
|
162
|
-
* `rpc.agent.stream` take it as their first argument and type the rest
|
|
163
|
-
* against it.
|
|
164
|
-
*/
|
|
165
|
-
export const agentCallOptions = (input: AgentInput): AgentInput => ({
|
|
166
|
-
message: input.message,
|
|
167
|
-
threadId: input.threadId,
|
|
168
|
-
resourceId: input.resourceId,
|
|
169
|
-
...(input.attachments ? { attachments: input.attachments } : {}),
|
|
170
|
-
...(input.model ? { model: input.model } : {}),
|
|
171
|
-
...(input.temperature !== undefined
|
|
172
|
-
? { temperature: input.temperature }
|
|
173
|
-
: {}),
|
|
174
|
-
...(input.context ? { context: input.context } : {}),
|
|
175
|
-
})
|
|
176
|
-
|
|
177
|
-
export type StreamAgentOptions = {
|
|
178
|
-
requiresToolApproval?: 'all' | 'explicit' | false
|
|
179
|
-
onRunCreated?: (runId: string) => void
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
export const APPROVAL_REQUIRED: unique symbol = Symbol(
|
|
183
|
-
'pikku.ai.approvalRequired'
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* In-process brand proving a credential request was produced by pikku itself and
|
|
188
|
-
* not by tool output an attacker can influence. Never serialized — a value that
|
|
189
|
-
* has crossed a JSON boundary has lost the brand and is treated as untrusted.
|
|
190
|
-
*/
|
|
191
|
-
export const CREDENTIAL_REQUIRED: unique symbol = Symbol(
|
|
192
|
-
'pikku.ai.credentialRequired'
|
|
193
|
-
)
|
|
194
|
-
|
|
195
|
-
export class ToolApprovalRequired extends PikkuError {
|
|
196
|
-
public readonly toolCallId: string
|
|
197
|
-
public readonly toolName: string
|
|
198
|
-
public readonly args: unknown
|
|
199
|
-
public reason?: string
|
|
200
|
-
public readonly displayToolName?: string
|
|
201
|
-
public readonly displayArgs?: unknown
|
|
202
|
-
public readonly agentRunId?: string
|
|
203
|
-
|
|
204
|
-
constructor(
|
|
205
|
-
toolCallId: string,
|
|
206
|
-
toolName: string,
|
|
207
|
-
args: unknown,
|
|
208
|
-
reason?: string,
|
|
209
|
-
displayToolName?: string,
|
|
210
|
-
displayArgs?: unknown,
|
|
211
|
-
agentRunId?: string
|
|
212
|
-
) {
|
|
213
|
-
super(`Tool '${displayToolName ?? toolName}' requires approval`)
|
|
214
|
-
this.toolCallId = toolCallId
|
|
215
|
-
this.toolName = toolName
|
|
216
|
-
this.args = args
|
|
217
|
-
this.reason = reason
|
|
218
|
-
this.displayToolName = displayToolName
|
|
219
|
-
this.displayArgs = displayArgs
|
|
220
|
-
this.agentRunId = agentRunId
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
export class ToolCredentialRequired extends PikkuError {
|
|
225
|
-
public readonly toolCallId: string
|
|
226
|
-
public readonly toolName: string
|
|
227
|
-
public readonly args: unknown
|
|
228
|
-
public readonly credentialName: string
|
|
229
|
-
public readonly credentialType: 'oauth2' | 'apikey'
|
|
230
|
-
public readonly connectUrl?: string
|
|
231
|
-
|
|
232
|
-
constructor(
|
|
233
|
-
toolCallId: string,
|
|
234
|
-
toolName: string,
|
|
235
|
-
args: unknown,
|
|
236
|
-
credentialName: string,
|
|
237
|
-
credentialType: 'oauth2' | 'apikey',
|
|
238
|
-
connectUrl?: string
|
|
239
|
-
) {
|
|
240
|
-
super(`Tool '${toolName}' requires credential '${credentialName}'`)
|
|
241
|
-
this.toolCallId = toolCallId
|
|
242
|
-
this.toolName = toolName
|
|
243
|
-
this.args = args
|
|
244
|
-
this.credentialName = credentialName
|
|
245
|
-
this.credentialType = credentialType
|
|
246
|
-
this.connectUrl = connectUrl
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
export interface AddonCredentialRequirement {
|
|
251
|
-
credentialName: string
|
|
252
|
-
displayName: string
|
|
253
|
-
addonNamespace: string
|
|
254
|
-
type: 'wire'
|
|
255
|
-
oauth2: boolean
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
export function getAddonCredentialRequirements(
|
|
259
|
-
toolNames: string[]
|
|
260
|
-
): AddonCredentialRequirement[] {
|
|
261
|
-
const requirements = new Map<string, AddonCredentialRequirement>()
|
|
262
|
-
|
|
263
|
-
for (const toolName of toolNames) {
|
|
264
|
-
if (!toolName.includes(':')) continue
|
|
265
|
-
const resolved = resolveNamespace(toolName)
|
|
266
|
-
if (!resolved) continue
|
|
267
|
-
|
|
268
|
-
const credsMeta = pikkuState(resolved.package, 'package', 'credentialsMeta')
|
|
269
|
-
if (!credsMeta) continue
|
|
270
|
-
|
|
271
|
-
for (const [name, meta] of Object.entries(
|
|
272
|
-
credsMeta as Record<string, any>
|
|
273
|
-
)) {
|
|
274
|
-
if (meta.type === 'wire' && meta.oauth2 && !requirements.has(name)) {
|
|
275
|
-
requirements.set(name, {
|
|
276
|
-
credentialName: name,
|
|
277
|
-
displayName: meta.displayName ?? name,
|
|
278
|
-
addonNamespace: toolName.split(':')[0],
|
|
279
|
-
type: 'wire',
|
|
280
|
-
oauth2: true,
|
|
281
|
-
})
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
return [...requirements.values()]
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
export type StreamContext = {
|
|
290
|
-
channel: AgentStreamChannel
|
|
291
|
-
options?: StreamAgentOptions
|
|
292
|
-
delegateState?: { delegated: boolean }
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
export const resolveAgent = (
|
|
296
|
-
agentName: string
|
|
297
|
-
): { agent: CoreAgent; packageName: string | null; resolvedName: string } => {
|
|
298
|
-
if (!agentName) {
|
|
299
|
-
console.error(
|
|
300
|
-
'[resolveAgent] agentName is undefined/null! Stack:',
|
|
301
|
-
new Error().stack
|
|
302
|
-
)
|
|
303
|
-
throw new Error('resolveAgent called with undefined agentName')
|
|
304
|
-
}
|
|
305
|
-
const mainAgent = pikkuState(null, 'agent', 'agents').get(agentName)
|
|
306
|
-
if (mainAgent) {
|
|
307
|
-
return { agent: mainAgent, packageName: null, resolvedName: agentName }
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const colonIndex = agentName.indexOf(':')
|
|
311
|
-
if (colonIndex !== -1) {
|
|
312
|
-
const namespace = agentName.substring(0, colonIndex)
|
|
313
|
-
const localName = agentName.substring(colonIndex + 1)
|
|
314
|
-
const addons = pikkuState(null, 'addons', 'packages')
|
|
315
|
-
const pkgConfig = addons.get(namespace)
|
|
316
|
-
if (pkgConfig) {
|
|
317
|
-
const extAgent = pikkuState(pkgConfig.package, 'agent', 'agents').get(
|
|
318
|
-
localName
|
|
319
|
-
)
|
|
320
|
-
if (extAgent) {
|
|
321
|
-
return {
|
|
322
|
-
agent: extAgent,
|
|
323
|
-
packageName: pkgConfig.package,
|
|
324
|
-
resolvedName: localName,
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
throw new Error(`AI agent not found: ${agentName}`)
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
export async function assertAgentAuthorized(
|
|
334
|
-
agent: CoreAgent,
|
|
335
|
-
params: RunAgentParams,
|
|
336
|
-
packageName: string | null
|
|
337
|
-
): Promise<void> {
|
|
338
|
-
const session = params.sessionService
|
|
339
|
-
? await params.sessionService.get()
|
|
340
|
-
: undefined
|
|
341
|
-
|
|
342
|
-
if (agent.auth === true && !session) {
|
|
343
|
-
throw new MissingSessionError('Authentication required')
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
verifyScopes(agent.scopes, session)
|
|
347
|
-
|
|
348
|
-
const singletonServices = getSingletonServices()
|
|
349
|
-
const wire = params.sessionService
|
|
350
|
-
? createMiddlewareSessionWireProps(params.sessionService)
|
|
351
|
-
: { session: undefined }
|
|
352
|
-
|
|
353
|
-
await runPermissions({
|
|
354
|
-
funcPermissions: agent.permissions,
|
|
355
|
-
services: singletonServices,
|
|
356
|
-
wire: wire as PermissionWire,
|
|
357
|
-
data: {},
|
|
358
|
-
packageName,
|
|
359
|
-
label: 'agent',
|
|
360
|
-
})
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
export async function buildInstructions(
|
|
364
|
-
agentName: string,
|
|
365
|
-
packageName: string | null
|
|
366
|
-
): Promise<string> {
|
|
367
|
-
const meta = pikkuState(packageName, 'agent', 'agentsMeta')[agentName]
|
|
368
|
-
const parts: string[] = []
|
|
369
|
-
if (meta?.role) parts.push(meta.role)
|
|
370
|
-
if (meta?.personality) parts.push(meta.personality)
|
|
371
|
-
if (meta?.goal) parts.push(meta.goal)
|
|
372
|
-
let instructions = parts.join('\n\n')
|
|
373
|
-
|
|
374
|
-
if (meta?.tools?.length || meta?.workflows?.length) {
|
|
375
|
-
instructions +=
|
|
376
|
-
'\n\nTool usage rules:\n' +
|
|
377
|
-
'- Act immediately with the information given. Do NOT ask clarifying questions unless a required field is truly missing.\n' +
|
|
378
|
-
'- Only use fields defined in your tool schemas. Never mention or ask for fields that do not exist.\n' +
|
|
379
|
-
'- Never fill optional fields with placeholder or zero values. Omit them entirely unless the user provides a real value.\n' +
|
|
380
|
-
'- Never stuff unrelated information into the wrong field.\n' +
|
|
381
|
-
'- Keep responses concise.'
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
if (meta?.agents?.length) {
|
|
385
|
-
instructions +=
|
|
386
|
-
'\n\nWhen calling a sub-agent, provide a short session name that describes the task. ' +
|
|
387
|
-
'Use the same session name to continue a previous conversation with that agent. ' +
|
|
388
|
-
'Use a new session name for a new independent task. ' +
|
|
389
|
-
'When a request involves multiple actions for the same domain, combine them into a single sub-agent call rather than making separate calls.'
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
return instructions
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
export type ScopedChannel = AgentStreamChannel & {
|
|
396
|
-
approvals: Array<{
|
|
397
|
-
toolCallId: string
|
|
398
|
-
toolName: string
|
|
399
|
-
args: unknown
|
|
400
|
-
reason?: string
|
|
401
|
-
runId: string
|
|
402
|
-
}>
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
export function createScopedChannel(
|
|
406
|
-
parent: AgentStreamChannel,
|
|
407
|
-
agentName: string,
|
|
408
|
-
session: string
|
|
409
|
-
): ScopedChannel {
|
|
410
|
-
const capturedApprovals: ScopedChannel['approvals'] = []
|
|
411
|
-
|
|
412
|
-
return {
|
|
413
|
-
channelId: `${parent.channelId}:${agentName}:${session}`,
|
|
414
|
-
openingData: parent.openingData,
|
|
415
|
-
get state() {
|
|
416
|
-
return parent.state
|
|
417
|
-
},
|
|
418
|
-
get approvals() {
|
|
419
|
-
return capturedApprovals
|
|
420
|
-
},
|
|
421
|
-
close: () => {},
|
|
422
|
-
sendBinary: (data) => parent.sendBinary(data),
|
|
423
|
-
send: (event: AgentStreamEvent) => {
|
|
424
|
-
if (event.type === 'done') return
|
|
425
|
-
if (event.type === 'approval-request') {
|
|
426
|
-
capturedApprovals.push({
|
|
427
|
-
toolCallId: event.toolCallId,
|
|
428
|
-
toolName: event.toolName,
|
|
429
|
-
args: event.args,
|
|
430
|
-
...(event.reason !== undefined ? { reason: event.reason } : {}),
|
|
431
|
-
runId: event.runId,
|
|
432
|
-
})
|
|
433
|
-
return
|
|
434
|
-
}
|
|
435
|
-
if (
|
|
436
|
-
event.type === 'step-start' ||
|
|
437
|
-
event.type === 'text-delta' ||
|
|
438
|
-
event.type === 'reasoning-delta' ||
|
|
439
|
-
event.type === 'tool-call' ||
|
|
440
|
-
event.type === 'tool-result' ||
|
|
441
|
-
event.type === 'usage' ||
|
|
442
|
-
event.type === 'error'
|
|
443
|
-
) {
|
|
444
|
-
parent.send({ ...event, agent: agentName, session } as AgentStreamEvent)
|
|
445
|
-
} else {
|
|
446
|
-
parent.send(event)
|
|
447
|
-
}
|
|
448
|
-
},
|
|
449
|
-
setState: (s) => parent.setState(s),
|
|
450
|
-
getState: () => parent.getState(),
|
|
451
|
-
clearState: () => parent.clearState(),
|
|
452
|
-
remote: (funcName: string, data?: unknown) => parent.remote(funcName, data),
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
export function buildSubAgentRunInput(
|
|
457
|
-
message: string,
|
|
458
|
-
threadId: string,
|
|
459
|
-
resourceId: string,
|
|
460
|
-
parentContext?: string
|
|
461
|
-
): { message: string; threadId: string; resourceId: string; context?: string } {
|
|
462
|
-
return { message, threadId, resourceId, context: parentContext }
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
export async function buildToolDefs(
|
|
466
|
-
params: RunAgentParams,
|
|
467
|
-
agentSessionMap: Map<string, string>,
|
|
468
|
-
resourceId: string,
|
|
469
|
-
agentName: string,
|
|
470
|
-
packageName: string | null,
|
|
471
|
-
streamContext?: StreamContext,
|
|
472
|
-
agentMiddlewares?: PikkuAgentMiddlewareHooks[],
|
|
473
|
-
agentMode?: 'delegate' | 'supervise',
|
|
474
|
-
parentContext?: string
|
|
475
|
-
): Promise<{ tools: AgentToolDef[]; missingRpcs: string[] }> {
|
|
476
|
-
const singletonServices = getSingletonServices()
|
|
477
|
-
const tools: AgentToolDef[] = []
|
|
478
|
-
const missingRpcs: string[] = []
|
|
479
|
-
const approvalPolicy =
|
|
480
|
-
streamContext?.options?.requiresToolApproval ?? 'explicit'
|
|
481
|
-
|
|
482
|
-
const meta = pikkuState(packageName, 'agent', 'agentsMeta')[agentName]
|
|
483
|
-
if (!meta) return { tools, missingRpcs }
|
|
484
|
-
|
|
485
|
-
/**
|
|
486
|
-
* A tool's description is what the model is told it does, and the main thing
|
|
487
|
-
* it chooses between tools on. It does not survive into the meta registered at
|
|
488
|
-
* boot: `description` is classed as a verbose field, so the bundled copy has
|
|
489
|
-
* it stripped and `fnMeta.description` is always undefined — every tool was
|
|
490
|
-
* being offered under its own bare name regardless of what its author wrote.
|
|
491
|
-
*
|
|
492
|
-
* `getFunctionsMeta` reads the verbose file and falls back to the minimal one,
|
|
493
|
-
* recovering the authored description wherever the generated `.pikku`
|
|
494
|
-
* directory is readable. Where it is not — no `metaService`, or a deployment
|
|
495
|
-
* shipping only the stripped copy — tools fall back to their name, which is
|
|
496
|
-
* what they did before this lookup existed.
|
|
497
|
-
*/
|
|
498
|
-
const describedFunctions = await singletonServices.metaService
|
|
499
|
-
?.getFunctionsMeta()
|
|
500
|
-
.catch(() => undefined)
|
|
501
|
-
|
|
502
|
-
const session = params.sessionService
|
|
503
|
-
? await params.sessionService.get()
|
|
504
|
-
: null
|
|
505
|
-
|
|
506
|
-
const metaTools = meta.tools
|
|
507
|
-
const metaAgents = meta.agents
|
|
508
|
-
|
|
509
|
-
if (metaTools?.length) {
|
|
510
|
-
for (const toolName of metaTools) {
|
|
511
|
-
let fnMeta: any
|
|
512
|
-
let resolvedPkg: string | null = null
|
|
513
|
-
let schemas: Map<string, any>
|
|
514
|
-
|
|
515
|
-
const resolved = toolName.includes(':')
|
|
516
|
-
? resolveNamespace(toolName)
|
|
517
|
-
: null
|
|
518
|
-
|
|
519
|
-
let pikkuFuncId: string | undefined
|
|
520
|
-
|
|
521
|
-
if (resolved) {
|
|
522
|
-
resolvedPkg = resolved.package
|
|
523
|
-
pikkuFuncId = resolved.function
|
|
524
|
-
fnMeta = pikkuState(resolvedPkg, 'function', 'meta')[pikkuFuncId]
|
|
525
|
-
schemas = pikkuState(resolvedPkg, 'misc', 'schemas')
|
|
526
|
-
} else {
|
|
527
|
-
const rpcMeta = pikkuState(null, 'rpc', 'meta')
|
|
528
|
-
pikkuFuncId = rpcMeta[toolName]
|
|
529
|
-
if (!pikkuFuncId) {
|
|
530
|
-
missingRpcs.push(toolName)
|
|
531
|
-
continue
|
|
532
|
-
}
|
|
533
|
-
fnMeta = pikkuState(null, 'function', 'meta')[pikkuFuncId]
|
|
534
|
-
schemas = pikkuState(null, 'misc', 'schemas')
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
if (!fnMeta) {
|
|
538
|
-
missingRpcs.push(toolName)
|
|
539
|
-
continue
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
if (fnMeta.permissions?.length) {
|
|
543
|
-
if (!session) continue
|
|
544
|
-
const funcConfig = pikkuFuncId
|
|
545
|
-
? pikkuState(resolvedPkg, 'function', 'functions').get(pikkuFuncId)
|
|
546
|
-
: undefined
|
|
547
|
-
const allowed = await checkAuthPermissions(
|
|
548
|
-
funcConfig?.permissions,
|
|
549
|
-
session,
|
|
550
|
-
singletonServices,
|
|
551
|
-
resolvedPkg
|
|
552
|
-
)
|
|
553
|
-
if (!allowed) continue
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
const inputSchemaName = fnMeta?.inputSchemaName
|
|
557
|
-
let inputSchema = inputSchemaName
|
|
558
|
-
? schemas.get(inputSchemaName)
|
|
559
|
-
: undefined
|
|
560
|
-
if (
|
|
561
|
-
!inputSchema ||
|
|
562
|
-
(typeof inputSchema === 'object' &&
|
|
563
|
-
inputSchema.type === 'object' &&
|
|
564
|
-
!inputSchema.properties)
|
|
565
|
-
) {
|
|
566
|
-
inputSchema = { type: 'object', properties: {} }
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
const needsApproval =
|
|
570
|
-
approvalPolicy === 'all' ||
|
|
571
|
-
(approvalPolicy === 'explicit' && fnMeta?.approvalRequired)
|
|
572
|
-
|
|
573
|
-
let approvalDescriptionFn:
|
|
574
|
-
((input: unknown) => Promise<string>) | undefined
|
|
575
|
-
if (needsApproval && pikkuFuncId) {
|
|
576
|
-
const funcConfig = pikkuState(resolvedPkg, 'function', 'functions').get(
|
|
577
|
-
pikkuFuncId
|
|
578
|
-
)
|
|
579
|
-
if (funcConfig?.approvalDescription) {
|
|
580
|
-
const descFn = funcConfig.approvalDescription
|
|
581
|
-
const capturedPkg = resolvedPkg
|
|
582
|
-
const capturedAddonConfig = resolved?.addonConfig
|
|
583
|
-
const capturedNamespace = toolName.includes(':')
|
|
584
|
-
? toolName.slice(0, toolName.indexOf(':'))
|
|
585
|
-
: null
|
|
586
|
-
approvalDescriptionFn = async (input: unknown) => {
|
|
587
|
-
let services = singletonServices
|
|
588
|
-
if (capturedPkg) {
|
|
589
|
-
const addonInstance = capturedNamespace
|
|
590
|
-
? {
|
|
591
|
-
namespace: capturedNamespace,
|
|
592
|
-
secretOverrides: capturedAddonConfig?.secretOverrides,
|
|
593
|
-
variableOverrides: capturedAddonConfig?.variableOverrides,
|
|
594
|
-
credentialOverrides:
|
|
595
|
-
capturedAddonConfig?.credentialOverrides,
|
|
596
|
-
secretGrants: capturedAddonConfig?.secretGrants,
|
|
597
|
-
credentialGrants: capturedAddonConfig?.credentialGrants,
|
|
598
|
-
globalSecrets: capturedAddonConfig?.globalSecrets,
|
|
599
|
-
globalCredentials: capturedAddonConfig?.globalCredentials,
|
|
600
|
-
}
|
|
601
|
-
: undefined
|
|
602
|
-
services = await getOrCreatePackageSingletonServices(
|
|
603
|
-
capturedPkg,
|
|
604
|
-
singletonServices,
|
|
605
|
-
addonInstance
|
|
606
|
-
)
|
|
607
|
-
}
|
|
608
|
-
return descFn(services, input)
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
tools.push({
|
|
614
|
-
name: toolName.replaceAll('@', '_').replaceAll(':', '__'),
|
|
615
|
-
description:
|
|
616
|
-
describedFunctions?.[pikkuFuncId]?.description ||
|
|
617
|
-
fnMeta?.description ||
|
|
618
|
-
toolName,
|
|
619
|
-
inputSchema,
|
|
620
|
-
needsApproval: needsApproval || undefined,
|
|
621
|
-
approvalDescriptionFn,
|
|
622
|
-
readonly: fnMeta?.readonly || undefined,
|
|
623
|
-
execute: async (toolInput: unknown) => {
|
|
624
|
-
const wire: PikkuRawWire = params.sessionService
|
|
625
|
-
? { ...createMiddlewareSessionWireProps(params.sessionService) }
|
|
626
|
-
: {}
|
|
627
|
-
const rpcService = new ContextAwareRPCService(
|
|
628
|
-
singletonServices,
|
|
629
|
-
wire,
|
|
630
|
-
{ sessionService: params.sessionService }
|
|
631
|
-
)
|
|
632
|
-
return rpcService.rpc(toolName, toolInput)
|
|
633
|
-
},
|
|
634
|
-
})
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
if (metaAgents?.length) {
|
|
639
|
-
const allAgentsMeta = pikkuState(null, 'agent', 'agentsMeta')
|
|
640
|
-
|
|
641
|
-
for (const subAgentName of metaAgents) {
|
|
642
|
-
const subMeta = allAgentsMeta[subAgentName]
|
|
643
|
-
if (!subMeta) {
|
|
644
|
-
singletonServices.logger.warn(
|
|
645
|
-
`Sub-agent '${subAgentName}' not found in agent registry`
|
|
646
|
-
)
|
|
647
|
-
continue
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
if (subMeta.permissions?.length) {
|
|
651
|
-
if (!session) continue
|
|
652
|
-
const subAgent = pikkuState(null, 'agent', 'agents').get(subAgentName)
|
|
653
|
-
const allowed = await checkAuthPermissions(
|
|
654
|
-
subAgent?.permissions,
|
|
655
|
-
session,
|
|
656
|
-
singletonServices
|
|
657
|
-
)
|
|
658
|
-
if (!allowed) continue
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
tools.push({
|
|
662
|
-
name: subAgentName,
|
|
663
|
-
description: subMeta.description,
|
|
664
|
-
forwardsApproval: true,
|
|
665
|
-
inputSchema: {
|
|
666
|
-
type: 'object',
|
|
667
|
-
properties: {
|
|
668
|
-
message: { type: 'string' },
|
|
669
|
-
session: {
|
|
670
|
-
type: 'string',
|
|
671
|
-
description: 'Short session label for thread continuity',
|
|
672
|
-
},
|
|
673
|
-
},
|
|
674
|
-
required: ['message', 'session'],
|
|
675
|
-
},
|
|
676
|
-
execute: async (toolInput: unknown) => {
|
|
677
|
-
const { message, session } = toolInput as {
|
|
678
|
-
message: string
|
|
679
|
-
session: string
|
|
680
|
-
}
|
|
681
|
-
const sessionKey = `${subAgentName}::${session}`
|
|
682
|
-
let threadId = agentSessionMap.get(sessionKey)
|
|
683
|
-
if (!threadId) {
|
|
684
|
-
threadId = randomUUID()
|
|
685
|
-
agentSessionMap.set(sessionKey, threadId)
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
if (streamContext) {
|
|
689
|
-
const isDelegate = agentMode !== 'supervise'
|
|
690
|
-
if (isDelegate && streamContext.delegateState) {
|
|
691
|
-
streamContext.delegateState.delegated = true
|
|
692
|
-
}
|
|
693
|
-
const { channel } = streamContext
|
|
694
|
-
channel.send({
|
|
695
|
-
type: 'agent-call',
|
|
696
|
-
agentName: subAgentName,
|
|
697
|
-
session,
|
|
698
|
-
input: message,
|
|
699
|
-
})
|
|
700
|
-
const subChannel = createScopedChannel(
|
|
701
|
-
channel,
|
|
702
|
-
subAgentName,
|
|
703
|
-
session
|
|
704
|
-
)
|
|
705
|
-
const effectiveChannel = isDelegate
|
|
706
|
-
? subChannel
|
|
707
|
-
: {
|
|
708
|
-
...subChannel,
|
|
709
|
-
send: (event: AgentStreamEvent) => {
|
|
710
|
-
if (
|
|
711
|
-
event.type === 'text-delta' ||
|
|
712
|
-
event.type === 'reasoning-delta'
|
|
713
|
-
)
|
|
714
|
-
return
|
|
715
|
-
subChannel.send(event)
|
|
716
|
-
},
|
|
717
|
-
}
|
|
718
|
-
const resultText = await streamAgent(
|
|
719
|
-
subAgentName,
|
|
720
|
-
buildSubAgentRunInput(
|
|
721
|
-
message,
|
|
722
|
-
threadId,
|
|
723
|
-
resourceId,
|
|
724
|
-
parentContext
|
|
725
|
-
),
|
|
726
|
-
effectiveChannel,
|
|
727
|
-
params,
|
|
728
|
-
agentSessionMap,
|
|
729
|
-
streamContext.options
|
|
730
|
-
)
|
|
731
|
-
if (subChannel.approvals.length > 0) {
|
|
732
|
-
return {
|
|
733
|
-
[APPROVAL_REQUIRED]: true,
|
|
734
|
-
__approvalRequired: true,
|
|
735
|
-
toolName: subAgentName,
|
|
736
|
-
args: toolInput,
|
|
737
|
-
agentRunId: subChannel.approvals[0].runId,
|
|
738
|
-
subApprovals: subChannel.approvals,
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
channel.send({
|
|
742
|
-
type: 'agent-result',
|
|
743
|
-
agentName: subAgentName,
|
|
744
|
-
session,
|
|
745
|
-
result: resultText,
|
|
746
|
-
})
|
|
747
|
-
return resultText
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
const result = await runAgent(
|
|
751
|
-
subAgentName,
|
|
752
|
-
buildSubAgentRunInput(message, threadId, resourceId, parentContext),
|
|
753
|
-
params,
|
|
754
|
-
agentSessionMap
|
|
755
|
-
)
|
|
756
|
-
if (
|
|
757
|
-
result.status === 'suspended' &&
|
|
758
|
-
result.pendingApprovals?.length
|
|
759
|
-
) {
|
|
760
|
-
return {
|
|
761
|
-
[APPROVAL_REQUIRED]: true,
|
|
762
|
-
__approvalRequired: true,
|
|
763
|
-
toolName: subAgentName,
|
|
764
|
-
args: toolInput,
|
|
765
|
-
agentRunId: result.runId,
|
|
766
|
-
subApprovals: result.pendingApprovals.map((a) => ({
|
|
767
|
-
toolCallId: a.toolCallId,
|
|
768
|
-
toolName: a.toolName,
|
|
769
|
-
args: a.args,
|
|
770
|
-
reason: a.reason,
|
|
771
|
-
runId: a.runId,
|
|
772
|
-
})),
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
return result.object ?? result.text
|
|
776
|
-
},
|
|
777
|
-
})
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
const metaWorkflows = meta.workflows
|
|
782
|
-
if (metaWorkflows?.length) {
|
|
783
|
-
const workflowMetaMap = pikkuState(null, 'workflows', 'meta')
|
|
784
|
-
const functionMeta = pikkuState(null, 'function', 'meta')
|
|
785
|
-
const schemas = pikkuState(null, 'misc', 'schemas')
|
|
786
|
-
|
|
787
|
-
for (const workflowName of metaWorkflows) {
|
|
788
|
-
const wfMeta = workflowMetaMap[workflowName]
|
|
789
|
-
if (!wfMeta) {
|
|
790
|
-
missingRpcs.push(workflowName)
|
|
791
|
-
continue
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
const inputSchemaName = wfMeta.pikkuFuncId
|
|
795
|
-
? functionMeta[wfMeta.pikkuFuncId]?.inputSchemaName
|
|
796
|
-
: undefined
|
|
797
|
-
let inputSchema = inputSchemaName
|
|
798
|
-
? schemas.get(inputSchemaName)
|
|
799
|
-
: undefined
|
|
800
|
-
if (
|
|
801
|
-
!inputSchema ||
|
|
802
|
-
(typeof inputSchema === 'object' &&
|
|
803
|
-
inputSchema.type === 'object' &&
|
|
804
|
-
!inputSchema.properties)
|
|
805
|
-
) {
|
|
806
|
-
inputSchema = { type: 'object', properties: {} }
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
tools.push({
|
|
810
|
-
name: workflowName,
|
|
811
|
-
description: wfMeta.description || workflowName,
|
|
812
|
-
inputSchema,
|
|
813
|
-
execute: async (toolInput: unknown) => {
|
|
814
|
-
const workflowService = singletonServices.workflowService
|
|
815
|
-
if (!workflowService) {
|
|
816
|
-
throw new Error(
|
|
817
|
-
`workflowService is not configured — cannot run workflow tool '${workflowName}'`
|
|
818
|
-
)
|
|
819
|
-
}
|
|
820
|
-
const wire: PikkuRawWire = params.sessionService
|
|
821
|
-
? { ...createMiddlewareSessionWireProps(params.sessionService) }
|
|
822
|
-
: {}
|
|
823
|
-
const rpcService = new ContextAwareRPCService(
|
|
824
|
-
singletonServices,
|
|
825
|
-
wire,
|
|
826
|
-
{ sessionService: params.sessionService }
|
|
827
|
-
)
|
|
828
|
-
return workflowService.runToCompletion(
|
|
829
|
-
workflowName,
|
|
830
|
-
toolInput,
|
|
831
|
-
rpcService,
|
|
832
|
-
{ wire: { type: 'internal' } }
|
|
833
|
-
)
|
|
834
|
-
},
|
|
835
|
-
})
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
for (const tool of tools) {
|
|
840
|
-
const originalExecute = tool.execute
|
|
841
|
-
tool.execute = async (toolInput: unknown) => {
|
|
842
|
-
try {
|
|
843
|
-
return await originalExecute(toolInput)
|
|
844
|
-
} catch (err: any) {
|
|
845
|
-
if (err?.payload?.error === 'missing_credential') {
|
|
846
|
-
return {
|
|
847
|
-
[CREDENTIAL_REQUIRED]: true,
|
|
848
|
-
__credentialRequired: true,
|
|
849
|
-
...err.payload,
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
singletonServices.logger.error(
|
|
853
|
-
`AI agent tool '${tool.name}' threw during execute()`,
|
|
854
|
-
err
|
|
855
|
-
)
|
|
856
|
-
throw err
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
const hasToolHooks = agentMiddlewares?.some(
|
|
862
|
-
(mw) => mw.beforeToolCall || mw.afterToolCall
|
|
863
|
-
)
|
|
864
|
-
if (hasToolHooks) {
|
|
865
|
-
for (const tool of tools) {
|
|
866
|
-
const originalExecute = tool.execute
|
|
867
|
-
tool.execute = async (toolInput: unknown) => {
|
|
868
|
-
const toolCallId = randomUUID()
|
|
869
|
-
let args = (toolInput ?? {}) as Record<string, unknown>
|
|
870
|
-
|
|
871
|
-
for (const mw of agentMiddlewares!) {
|
|
872
|
-
if (mw.beforeToolCall) {
|
|
873
|
-
const beforeResult = await mw.beforeToolCall(singletonServices, {
|
|
874
|
-
toolName: tool.name,
|
|
875
|
-
toolCallId,
|
|
876
|
-
args,
|
|
877
|
-
})
|
|
878
|
-
if (beforeResult && 'args' in beforeResult) {
|
|
879
|
-
args = beforeResult.args
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
const startTime = Date.now()
|
|
885
|
-
let result: unknown
|
|
886
|
-
let execError: unknown
|
|
887
|
-
try {
|
|
888
|
-
result = await originalExecute(args)
|
|
889
|
-
} catch (err: any) {
|
|
890
|
-
execError = err
|
|
891
|
-
if (err?.payload?.error === 'missing_credential') throw err
|
|
892
|
-
result = err instanceof Error ? err.message : String(err)
|
|
893
|
-
}
|
|
894
|
-
const durationMs = Date.now() - startTime
|
|
895
|
-
|
|
896
|
-
for (let i = agentMiddlewares!.length - 1; i >= 0; i--) {
|
|
897
|
-
const mw = agentMiddlewares![i]
|
|
898
|
-
if (mw.afterToolCall) {
|
|
899
|
-
const afterResult = await mw.afterToolCall(singletonServices, {
|
|
900
|
-
toolName: tool.name,
|
|
901
|
-
toolCallId,
|
|
902
|
-
args,
|
|
903
|
-
result,
|
|
904
|
-
durationMs,
|
|
905
|
-
})
|
|
906
|
-
if (afterResult && 'result' in afterResult) {
|
|
907
|
-
result = afterResult.result
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
if (execError) throw execError
|
|
913
|
-
return result
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
return { tools, missingRpcs }
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
export async function prepareAgentRun(
|
|
922
|
-
agentName: string,
|
|
923
|
-
input: AgentInput,
|
|
924
|
-
params: RunAgentParams,
|
|
925
|
-
agentSessionMap: Map<string, string>,
|
|
926
|
-
streamContext?: StreamContext
|
|
927
|
-
) {
|
|
928
|
-
const singletonServices = getSingletonServices()
|
|
929
|
-
const { agent, packageName, resolvedName } = resolveAgent(agentName)
|
|
930
|
-
|
|
931
|
-
await assertAgentAuthorized(agent, params, packageName)
|
|
932
|
-
|
|
933
|
-
let agentRunner = singletonServices.agentRunner
|
|
934
|
-
if (!agentRunner) {
|
|
935
|
-
throw new AIProviderNotConfiguredError()
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
if (params.getCredential && agentRunner.withApiKey) {
|
|
939
|
-
const aiCredential = await params.getCredential<{ apiKey: string }>(
|
|
940
|
-
'AI_API_KEY'
|
|
941
|
-
)
|
|
942
|
-
if (aiCredential?.apiKey?.trim()) {
|
|
943
|
-
agentRunner = agentRunner.withApiKey(aiCredential.apiKey)
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
const { storage } = resolveMemoryServices(agent, singletonServices)
|
|
948
|
-
const memoryConfig = agent.memory
|
|
949
|
-
const threadId = input.threadId
|
|
950
|
-
|
|
951
|
-
const agentsMeta = pikkuState(packageName, 'agent', 'agentsMeta')
|
|
952
|
-
const meta = agentsMeta[resolvedName]
|
|
953
|
-
const outputSchemaName = meta?.outputSchema
|
|
954
|
-
const outputSchema = outputSchemaName
|
|
955
|
-
? pikkuState(packageName, 'misc', 'schemas').get(outputSchemaName)
|
|
956
|
-
: undefined
|
|
957
|
-
|
|
958
|
-
const workingMemorySchemaName = meta?.workingMemorySchema ?? null
|
|
959
|
-
const workingMemoryJsonSchema = workingMemorySchemaName
|
|
960
|
-
? pikkuState(packageName, 'misc', 'schemas').get(workingMemorySchemaName)
|
|
961
|
-
: undefined
|
|
962
|
-
|
|
963
|
-
if (storage) {
|
|
964
|
-
let thread: Awaited<ReturnType<typeof storage.getThread>> | null = null
|
|
965
|
-
try {
|
|
966
|
-
thread = await storage.getThread(threadId)
|
|
967
|
-
} catch {
|
|
968
|
-
thread = null
|
|
969
|
-
}
|
|
970
|
-
if (thread) {
|
|
971
|
-
assertResourceOwner(input.resourceId, thread.resourceId, 'thread')
|
|
972
|
-
} else {
|
|
973
|
-
await storage.createThread(input.resourceId, { threadId })
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
|
|
977
|
-
let messages: AgentMessage[] = []
|
|
978
|
-
if (storage) {
|
|
979
|
-
// knowledge: decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md
|
|
980
|
-
await awaitPendingInterruptNote(threadId)
|
|
981
|
-
messages = await storage.getMessages(threadId, {
|
|
982
|
-
lastN: memoryConfig?.lastMessages ?? 20,
|
|
983
|
-
})
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
const contextMessages = await loadContextMessages(
|
|
987
|
-
memoryConfig,
|
|
988
|
-
storage,
|
|
989
|
-
input,
|
|
990
|
-
workingMemoryJsonSchema
|
|
991
|
-
)
|
|
992
|
-
|
|
993
|
-
const userContent: AgentMessage['content'] = input.attachments?.length
|
|
994
|
-
? [
|
|
995
|
-
// knowledge: decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md
|
|
996
|
-
...(input.message
|
|
997
|
-
? [{ type: 'text' as const, text: input.message }]
|
|
998
|
-
: []),
|
|
999
|
-
...input.attachments.map(
|
|
1000
|
-
(a) =>
|
|
1001
|
-
({
|
|
1002
|
-
type: a.type,
|
|
1003
|
-
data: a.data,
|
|
1004
|
-
url: a.url,
|
|
1005
|
-
mediaType: a.mediaType,
|
|
1006
|
-
...(a.filename ? { filename: a.filename } : {}),
|
|
1007
|
-
}) as AgentContentPart
|
|
1008
|
-
),
|
|
1009
|
-
]
|
|
1010
|
-
: input.message
|
|
1011
|
-
|
|
1012
|
-
const userMessage: AgentMessage = {
|
|
1013
|
-
id: randomUUID(),
|
|
1014
|
-
role: 'user',
|
|
1015
|
-
content: userContent,
|
|
1016
|
-
createdAt: new Date(),
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
const allMessages = [...contextMessages, ...messages, userMessage]
|
|
1020
|
-
const trimmedMessages = trimMessages(allMessages)
|
|
1021
|
-
|
|
1022
|
-
const agentMiddlewares: PikkuAgentMiddlewareHooks[] =
|
|
1023
|
-
agent.agentMiddleware ?? []
|
|
1024
|
-
|
|
1025
|
-
const { tools, missingRpcs } = await buildToolDefs(
|
|
1026
|
-
params,
|
|
1027
|
-
agentSessionMap,
|
|
1028
|
-
input.resourceId,
|
|
1029
|
-
resolvedName,
|
|
1030
|
-
packageName,
|
|
1031
|
-
streamContext,
|
|
1032
|
-
agentMiddlewares,
|
|
1033
|
-
agent.agentMode,
|
|
1034
|
-
input.context
|
|
1035
|
-
)
|
|
1036
|
-
|
|
1037
|
-
let instructions = await buildInstructions(resolvedName, packageName)
|
|
1038
|
-
if (input.context) {
|
|
1039
|
-
instructions = `${instructions}\n\nCurrent context (use these identifiers directly in tool calls — do not ask the user for them):\n${input.context}`
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
const resolved = resolveModelConfig(resolvedName, agent)
|
|
1043
|
-
|
|
1044
|
-
if (input.model) {
|
|
1045
|
-
resolved.model = resolveModelConfig(resolvedName, {
|
|
1046
|
-
...agent,
|
|
1047
|
-
model: input.model,
|
|
1048
|
-
}).model
|
|
1049
|
-
}
|
|
1050
|
-
if (input.temperature !== undefined) {
|
|
1051
|
-
resolved.temperature = input.temperature
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
const maxSteps = resolved.maxSteps ?? 10
|
|
1055
|
-
|
|
1056
|
-
const runnerParams: AgentRunnerParams = {
|
|
1057
|
-
model: resolved.model,
|
|
1058
|
-
temperature: resolved.temperature,
|
|
1059
|
-
instructions,
|
|
1060
|
-
messages: trimmedMessages,
|
|
1061
|
-
tools,
|
|
1062
|
-
maxSteps: 1,
|
|
1063
|
-
toolChoice: agent.toolChoice ?? 'auto',
|
|
1064
|
-
providerOptions: agent.providerOptions,
|
|
1065
|
-
outputSchema,
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
return {
|
|
1069
|
-
agent,
|
|
1070
|
-
packageName,
|
|
1071
|
-
resolvedName,
|
|
1072
|
-
agentRunner,
|
|
1073
|
-
storage,
|
|
1074
|
-
memoryConfig,
|
|
1075
|
-
threadId,
|
|
1076
|
-
userMessage,
|
|
1077
|
-
runnerParams,
|
|
1078
|
-
maxSteps,
|
|
1079
|
-
missingRpcs,
|
|
1080
|
-
workingMemoryJsonSchema,
|
|
1081
|
-
workingMemorySchemaName,
|
|
1082
|
-
}
|
|
1083
|
-
}
|