@skein-js/agent-protocol 0.4.0 → 0.5.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/dist/index.d.ts +9 -1
- package/dist/index.js +53 -15
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GraphSchema, SkeinStore, RunQueue, RunEventBus, AuthEngine, Assistant, Config, StreamMode, Metadata, MultitaskStrategy, RunFrame, DefaultValues, Run, RunStatus, StorePutOptions, Item, StoreSearchQuery, SearchItem, Thread, ThreadSearchQuery, ThreadState, StoreRepo } from '@skein-js/core';
|
|
1
|
+
import { GraphSchema, SkeinStore, RunQueue, RunEventBus, AuthEngine, Assistant, AuthUser, Config, StreamMode, Metadata, MultitaskStrategy, RunFrame, DefaultValues, Run, RunStatus, StorePutOptions, Item, StoreSearchQuery, SearchItem, Thread, ThreadSearchQuery, ThreadState, StoreRepo } from '@skein-js/core';
|
|
2
2
|
import { CompiledGraph, BaseCheckpointSaver, BaseStore, Item as Item$1, Operation, OperationResults } from '@langchain/langgraph';
|
|
3
3
|
|
|
4
4
|
/** A factory export: called (optionally with per-run config) to produce a compiled graph. */
|
|
@@ -119,6 +119,14 @@ interface ProtocolContext {
|
|
|
119
119
|
deps: ResolvedDeps;
|
|
120
120
|
control: RunControlRegistry;
|
|
121
121
|
locks: ThreadLocks;
|
|
122
|
+
/**
|
|
123
|
+
* The authenticated caller for the current request, populated by the authorizing handler wrapper
|
|
124
|
+
* so the run service can stamp it onto a run's kwargs. Undefined when no auth engine is
|
|
125
|
+
* configured (the default), matching `langgraph dev` — no principal is injected into the graph.
|
|
126
|
+
*/
|
|
127
|
+
authUser?: AuthUser;
|
|
128
|
+
/** The current request's authenticated permission scopes (`AuthContext.scopes`), stamped with {@link authUser}. */
|
|
129
|
+
authScopes?: string[];
|
|
122
130
|
}
|
|
123
131
|
declare function createContext(deps: ProtocolDeps): ProtocolContext;
|
|
124
132
|
|
package/dist/index.js
CHANGED
|
@@ -622,7 +622,10 @@ var RESERVED_CONFIGURABLE_KEYS = /* @__PURE__ */ new Set([
|
|
|
622
622
|
"checkpoint_id",
|
|
623
623
|
"checkpoint_ns",
|
|
624
624
|
"checkpoint_map",
|
|
625
|
-
"checkpoint"
|
|
625
|
+
"checkpoint",
|
|
626
|
+
"langgraph_auth_user",
|
|
627
|
+
"langgraph_auth_user_id",
|
|
628
|
+
"langgraph_auth_permissions"
|
|
626
629
|
]);
|
|
627
630
|
function sanitizeConfigurable(configurable) {
|
|
628
631
|
if (!configurable) return {};
|
|
@@ -633,10 +636,32 @@ function sanitizeConfigurable(configurable) {
|
|
|
633
636
|
}
|
|
634
637
|
return clean;
|
|
635
638
|
}
|
|
639
|
+
function withAuthUser(configurable, authUser, scopes) {
|
|
640
|
+
if (!authUser) return configurable;
|
|
641
|
+
return {
|
|
642
|
+
...configurable,
|
|
643
|
+
langgraph_auth_user: authUser,
|
|
644
|
+
langgraph_auth_user_id: authUser.identity,
|
|
645
|
+
langgraph_auth_permissions: scopes ?? authUser.permissions
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
function toFactoryConfigurable(kwargs) {
|
|
649
|
+
const configurable = withAuthUser(
|
|
650
|
+
sanitizeConfigurable(kwargs.config?.configurable),
|
|
651
|
+
kwargs.auth_user,
|
|
652
|
+
kwargs.auth_scopes
|
|
653
|
+
);
|
|
654
|
+
return Object.keys(configurable).length > 0 ? configurable : void 0;
|
|
655
|
+
}
|
|
636
656
|
function toGraphCallOptions(kwargs, threadId, signal) {
|
|
637
657
|
const options = {
|
|
638
|
-
// Drop server-owned keys from the client's configurable,
|
|
639
|
-
|
|
658
|
+
// Drop server-owned keys from the client's configurable, force this thread's id, then stamp the
|
|
659
|
+
// authenticated caller so the graph can authorize off `configurable.langgraph_auth_user`.
|
|
660
|
+
configurable: withAuthUser(
|
|
661
|
+
{ ...sanitizeConfigurable(kwargs.config?.configurable), thread_id: threadId },
|
|
662
|
+
kwargs.auth_user,
|
|
663
|
+
kwargs.auth_scopes
|
|
664
|
+
),
|
|
640
665
|
streamMode: normalizeModes(kwargs.stream_mode),
|
|
641
666
|
signal
|
|
642
667
|
};
|
|
@@ -717,7 +742,12 @@ function describeInterrupts(snapshot) {
|
|
|
717
742
|
// src/runs/run-engine.ts
|
|
718
743
|
async function resolveGraph(deps, graphId, kwargs) {
|
|
719
744
|
const resolved = await deps.graphs.load(graphId);
|
|
720
|
-
const graph = typeof resolved === "function" ?
|
|
745
|
+
const graph = typeof resolved === "function" ? (
|
|
746
|
+
// Expose the authenticated caller to a graph *factory* too, so a factory that branches on the
|
|
747
|
+
// principal sees the same `langgraph_auth_user` a node reads — sanitized identically, so a
|
|
748
|
+
// client can't spoof it via its own configurable.
|
|
749
|
+
await resolved({ configurable: toFactoryConfigurable(kwargs) })
|
|
750
|
+
) : resolved;
|
|
721
751
|
graph.checkpointer = deps.checkpointer;
|
|
722
752
|
graph.store = new SkeinBaseStore(deps.store.store);
|
|
723
753
|
return graph;
|
|
@@ -855,7 +885,7 @@ async function executeRun(deps, exec) {
|
|
|
855
885
|
}
|
|
856
886
|
|
|
857
887
|
// src/runs/run-service.ts
|
|
858
|
-
function toKwargs(input) {
|
|
888
|
+
function toKwargs(input, authUser, authScopes) {
|
|
859
889
|
const kwargs = {};
|
|
860
890
|
if (input.input !== void 0) kwargs.input = input.input;
|
|
861
891
|
if (input.command !== void 0) kwargs.command = input.command;
|
|
@@ -864,10 +894,14 @@ function toKwargs(input) {
|
|
|
864
894
|
if (input.stream_mode !== void 0) kwargs.stream_mode = input.stream_mode;
|
|
865
895
|
if (input.interrupt_before !== void 0) kwargs.interrupt_before = input.interrupt_before;
|
|
866
896
|
if (input.interrupt_after !== void 0) kwargs.interrupt_after = input.interrupt_after;
|
|
897
|
+
if (authUser !== void 0) {
|
|
898
|
+
kwargs.auth_user = authUser;
|
|
899
|
+
if (authScopes !== void 0) kwargs.auth_scopes = authScopes;
|
|
900
|
+
}
|
|
867
901
|
return kwargs;
|
|
868
902
|
}
|
|
869
903
|
function createRunService(ctx) {
|
|
870
|
-
const { deps, control, locks } = ctx;
|
|
904
|
+
const { deps, control, locks, authUser, authScopes } = ctx;
|
|
871
905
|
const requireThread = async (threadId) => {
|
|
872
906
|
const thread = await deps.store.threads.get(threadId);
|
|
873
907
|
if (!thread) throw SkeinHttpError5.notFound(`Thread "${threadId}" not found.`);
|
|
@@ -931,7 +965,7 @@ function createRunService(ctx) {
|
|
|
931
965
|
async createWait(input) {
|
|
932
966
|
const assistant = await requireAssistant(input.assistant_id);
|
|
933
967
|
const thread = await ensureThread(input.thread_id);
|
|
934
|
-
const kwargs = toKwargs(input);
|
|
968
|
+
const kwargs = toKwargs(input, authUser, authScopes);
|
|
935
969
|
const run = await createPendingRun(input, thread.thread_id, assistant.assistant_id, kwargs);
|
|
936
970
|
await stampGraphOnThread(thread, assistant);
|
|
937
971
|
const outcome = await runInline(run, kwargs);
|
|
@@ -940,7 +974,7 @@ function createRunService(ctx) {
|
|
|
940
974
|
async createStream(input) {
|
|
941
975
|
const assistant = await requireAssistant(input.assistant_id);
|
|
942
976
|
const thread = await ensureThread(input.thread_id);
|
|
943
|
-
const kwargs = toKwargs(input);
|
|
977
|
+
const kwargs = toKwargs(input, authUser, authScopes);
|
|
944
978
|
const run = await createPendingRun(input, thread.thread_id, assistant.assistant_id, kwargs);
|
|
945
979
|
await stampGraphOnThread(thread, assistant);
|
|
946
980
|
void runInline(run, kwargs).catch(
|
|
@@ -951,7 +985,7 @@ function createRunService(ctx) {
|
|
|
951
985
|
async createBackground(threadId, input) {
|
|
952
986
|
const assistant = await requireAssistant(input.assistant_id);
|
|
953
987
|
const thread = await requireThread(threadId);
|
|
954
|
-
const kwargs = toKwargs(input);
|
|
988
|
+
const kwargs = toKwargs(input, authUser, authScopes);
|
|
955
989
|
const run = await createPendingRun(
|
|
956
990
|
{ ...input, thread_id: threadId },
|
|
957
991
|
threadId,
|
|
@@ -1410,7 +1444,7 @@ var STUDIO_USER = {
|
|
|
1410
1444
|
};
|
|
1411
1445
|
function createAuthorizingHandlers(context, engine) {
|
|
1412
1446
|
const baseHandlers = createProtocolHandlers(buildProtocolService(context));
|
|
1413
|
-
const names = Object.keys(
|
|
1447
|
+
const names = Object.keys(ROUTE_AUTHZ);
|
|
1414
1448
|
const resolveAuthContext = async (req) => {
|
|
1415
1449
|
if (!engine.studioAuthDisabled && req.headers["x-auth-scheme"] === "langsmith") {
|
|
1416
1450
|
return { user: STUDIO_USER, scopes: [] };
|
|
@@ -1428,13 +1462,17 @@ function createAuthorizingHandlers(context, engine) {
|
|
|
1428
1462
|
value: authValue(req),
|
|
1429
1463
|
context: authContext
|
|
1430
1464
|
});
|
|
1431
|
-
if (!filters) return baseHandlers[name](req);
|
|
1432
|
-
const
|
|
1433
|
-
const scopedContext = {
|
|
1465
|
+
if (!filters && !authContext) return baseHandlers[name](req);
|
|
1466
|
+
const requestContext = {
|
|
1434
1467
|
...context,
|
|
1435
|
-
|
|
1468
|
+
authUser: authContext?.user,
|
|
1469
|
+
authScopes: authContext?.scopes,
|
|
1470
|
+
deps: filters ? {
|
|
1471
|
+
...context.deps,
|
|
1472
|
+
store: createAuthScopedStore(context.deps.store, engine, filters, route.resource)
|
|
1473
|
+
} : context.deps
|
|
1436
1474
|
};
|
|
1437
|
-
return createProtocolHandlers(buildProtocolService(
|
|
1475
|
+
return createProtocolHandlers(buildProtocolService(requestContext))[name](req);
|
|
1438
1476
|
};
|
|
1439
1477
|
}
|
|
1440
1478
|
return wrapped;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skein-js/agent-protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Framework-agnostic Agent Protocol engine for LangGraph.js — run engine, handlers, and SSE, driven entirely by injected dependencies.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Maina Wycliffe <wmmaina7@gmail.com>",
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"zod": "^3.25.76",
|
|
47
|
-
"@skein-js/core": "0.
|
|
47
|
+
"@skein-js/core": "0.5.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@langchain/langgraph": "^1.4.0",
|
|
51
51
|
"@langchain/langgraph-sdk": "^1.9.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@skein-js/storage-memory": "0.
|
|
54
|
+
"@skein-js/storage-memory": "0.5.0"
|
|
55
55
|
},
|
|
56
56
|
"publishConfig": {
|
|
57
57
|
"access": "public"
|